【复习1】 二分查找

【使用labuladong的算法小抄进行复习】

二分查找的思路并不复杂,但是算法实现的细节十分重要,区间是否开闭、大于小于号是否取等,如果没有理解这些细节,每次写二分查找只能靠菩萨保佑才能没有bug。

所有的二分查找基于以下框架

int binarySearch(int[] nums,int[] target)
{
    int left = 0,right = ...;
    while(...)
    {
        int mid = left + (right - left) / 2; //防止left+right溢出
        if(nums[mid]==target)
        {
            ...
        }
        else if(nums[mid] < target)
        {
            left =...
        }
        else if(nums[mid] > target)
        {
            right = ...
        }
    }
    return ...;
}

对于二分茶渣进行一步细分。

二分查找常见的有三种场景:寻找一个数、寻找左侧边界、寻找右侧边界。
一、寻找一个数

搜索一个数,如果存在,返回其索引,如果不存在,返回-1

int binarySearch(int[] nums, int target)
{
    int left = 0;
    int right = nums.length -1 ;//表示在[left,right]左右两端闭区间里面进行搜索
    while(left <= right){
            //当搜索区间为空时需要退出循环
            //当left=right时,搜索区间并不为空,不用推出循环
        int mid = left + (right - left)/2;
        if(nums[mid] == target)
        {
            return mid;
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;
            //由于mid已经搜索过,需要从搜索区间中剔除
        }
        else if(nums[mid] > targe)
        {
            right = mid - 1;
        }
    }
}

二、寻找左侧边界的二分搜索

如果存在多个重复数字的情况,需要查找最靠左端的target

或者数组中不存在target,寻找一个接近target的最左边界。

int left_bound(int[] nums,int target)
{
    int left = 0;
    int right = nums.length;
    while(left < right)
    {
        mid = (left + right)/2;
        if(nums[mid] == target)
        {
            right = mid
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;
        }
        else if(nums[mid] > target)
        {
            right = mid;
        }
    }
    return left;
}

三、寻找右侧边界的二分查找

int right_bound(int[] nums,int target)
{
    if(nums.length == 0)return -1;
    int left = 0;
    int right = nums.length;
    
    while(left < right)
    {
        mid = (left+right)/2;
        if(nums[mid] == target)
        {
            left = mid + 1;
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;
        }
        else if(nums[mid] > target)
        {
            right = mid;
        }
        
    }
    return left - 1;
}

 

posted @ 2020-09-13 16:26  yoyoyayababy  阅读(162)  评论(0编辑  收藏  举报