二分查找模板

二分查找模板

今天集中完成了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、这两个模板在一些情况下时都可以使用的

posted @ 2019-08-24 11:26  wunsiang  阅读(113)  评论(0)    收藏  举报