欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于二分法的一些误区

程序员文章站 2022-05-05 17:38:26
...

以前刷算法题的时候刷到二分查找,会被告知二分查找的一些固定写法,今天刷了几道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的题目(传送门),我自己也正在刷题中,共勉。

以上。

 

 

相关标签: binary search