二分查找模板
今天集中完成了35. 搜索插入位置等几道关于二分查找的基础题,对于这类问题有了一点新的认识,于此记录一下。
初步的两个模板
public int binarySearch_leftMedian(int[] nums,int target) {
int left = 0,right = nums.length - 1;
while (left < right){//注意,条件都用left < right
int mid = (left + right) >>> 1;//注意,取左中位数,一般left作为排除中位数的“主元素”时使用左中位数,则与之对应right作为排除中位数的“主元素”时使用右中位数
if(nums[mid] == x){
return mid;
}
else if(nums[mid] < x){
left = mid + 1;//先写要排除中位数的部分
}
else {
right = mid;//另一边不排除中位数,这样有助于理清楚最终返回哪个边界,如34.在排序数组中查找元素的第一个和最后一个位置35.搜索插入位置
}
}
return nums[left] == target ? left :-1;//在一些情况下(如数组中只有两个元素时),最终left(或right,因为跳出时left==right)所指的元素是没有经过判断的
}
public int binarySearch_rightMedian(int[] nums,int target) {
int left = 0,right = nums.length - 1;
while (left < right){//注意,条件都用left < right
int mid = (left + right + 1) >>> 1;//注意,取右中位数,一般left作为排除中位数的“主元素”时使用左中位数,则与之对应right作为排除中位数的“主元素”时使用右中位数
if(nums[mid] == x){
return mid;
}
else if(nums[mid] > x){
right = mid - 1;//先写要排除中位数的部分
}
else {
left = mid;//另一边不排除中位数,这样有助于理清楚最终返回哪个边界,如34.在排序数组中查找元素的第一个和最后一个位置35.搜索插入位置
}
}
return nums[right] == target ? right :-1;//在一些情况下(如数组中只有两个元素时),或right(或left,因为跳出时left==right)所指的元素是没有经过判断的
}
1、关于循环跳出条件left < right,跳出时left==right
2、int mid = (left + right) >>> 1,无符号右移避免left + right过大溢出,更能避免在计算右中位数时溢出,因为之前的mid = (right - left + 1)/2 + left的方式计算右中位数仍然可能溢出
3、一边排除中位数,另一边不排除中位数,这样有助于理清楚最终根据要求返回边界值
4、这两个模板在一些情况下时都可以使用的