关于二分法的一些误区

以前刷算法题的时候刷到二分查找,会被告知二分查找的一些固定写法,今天刷了几道leetcode,总结一下。

最简单的二分查找问题可以参见leetcode链接

简单叙述就是,在一个有序数组nums中查找某个值target,找到的话返回该target在nums中的下标,找不到则返回-1

以下是摘自另一篇博客的“标准”写法:
 

/**
 * 二分查找,找到该值在数组中的下标,否则为-1
 */
static int binarySerach(int[] array, int key) {
    int left = 0;
    int right = array.length - 1;

    // 这里必须是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] == key) {
            return mid;
        }
        else if (array[mid] < key) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }

    return -1;
}

 

上述代码的正确性朋友们可以自行验证,但是有几个问题:

1. while停止条件必须是low <= high吗?

2. 每次更新low或者high指针时必须用low = mid + 1和high = mid - 1吗?

 

解答:
1. 关于while的停止条件,其实并不一定是low <= high。个人理解:low和high指针只是限制了一个查找范围。

可以证明:
当low < high - 1,mid = low + (high - low) / 2 时,始终有low < mid < high成立。

所以,while循环体内mid的搜索范围为任何介于nums[low]和nums[high]的元素。

通过不断更新low或者high的值,我们不断将搜索范围缩小,直到nums[low]和nums[high]之间不包含任何元素,此时我们跳出循环。此时,nums[low]和nums[high]两者之间必定包含了我们要找的值,只要分别比较两者和target即可。

 

2. 在while中更新low或者high指针时,必须使用low = mid + 1或者high = mid - 1吗?

也不一定,从程序逻辑可以看出,只有在nums[mid] != target时,我们才会更新low或者high指针,而此时,将不将mid排除在搜索范围之内其实意义不大(或者说没有区别)。

 

最后,朋友们如果对二分查找感觉不是很熟练的话,可以刷一下LeetCode上关于binary search的题目(传送门),我自己也正在刷题中,共勉。

以上。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值