【常见面试算法】二分法-不但可知具体的位置,也可查左右边界

【转载】本文为CSDN博主「我还年轻我很平凡」的原创文章
原文链接:https://blog.csdn.net/weixin_43784989/article/details/98229031

1、简单二分

那么接下来,我们先来看看二分查找的最常用的场景:查一个有序数组的某一数字是否存在(下标)
图片说明

//target意为目标数字
public int searchNum(int target){
int l = 0;
int r = nums.length - 1;
while (l <= r) {
    int mid = l + ((r - l) >> 1);
    if(nums[mid] == target){
        return mid;
    } else if (target < nums[mid]){
        l = mid + 1;
    } else {
        r = mid - 1;
    }
}
return -1;//表示没有找到该数字
}

2、 复杂二分查找(查找左边界)

假设有一个有序数组{1,2,2,2,3},这个时候让你查找target=2的边界,计算之后返回的结果肯定是是按下标处理过后:(1,3)
这个时候你可能会觉得,这有啥?费这么大劲?用什么二分法?沙13吧?当然,这个数组长度非常短,费不着用什么二分法,一次遍历就可以解决。那么如果数组很长尼?O(N)和O(logN)你倾向与哪个?答案就在下面:配合着图和代码你就知道了:
图片说明

//target=2
public int findLeftBound(int target){
    int l = 0;
    int r = nums.length; //这里需要注意
    while (l < r){
        int mid = l + ((r - l) >> 1);
        if (nums[mid] >= target){  //这里需要注意
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    return l;
}

至于为什么会是这样?这其实就和作用域一样,左闭右开/左闭右闭,自己画个图就明白了

3、复杂二分查找(查找右边界)

其实和查找左边界没什么多大区别,只是在返回的时候需要注意,因为作用域是[L,R),所以在返回有右边界的时候-1再返回:

public int findRightBound(int target){
    int l = 0;
    int r = nums.length;
    while (l < r){
        int mid = l + ((r - l) >> 1);
        if (nums[mid] > target){
            r = mid;
        } else{
            l= mid + 1;
        }
    }
    return r - 1;
}
全部评论

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务