你能写出满分的二分查找算法吗

Posted 纵横千里,捭阖四方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你能写出满分的二分查找算法吗相关的知识,希望对你有一定的参考价值。

二分查找是分治的经典案例。分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如二分搜索、排序算法(快速排序,归并排序)等等……

任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。

二分查找就是将中间结果与目标进行比较,一次去掉一般,因此二分查找可以说是最简单、最典型的分治了。

废话少说,直接上菜:

public int binarySearch(int[] array, int low, int high, int target) 
        // 循环
        while (low <= high) 
            int mid = (low + high) /2;
            if (array[mid] == target) 
                return mid ; 
             else if (array[mid] > target) 
                // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                high = mid -1;
             else 
                // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                low = mid + 1;
            
        
          return -1;
    

这个代码能得多少分?我觉得是70,因为有个很重要的细节没有处理。在计算机中,除的效率非常低,一般可以使用移位来代替,也就是:

将:
int mid = (low + high) /2;
换成
int mid = (low + high)>>1;

如果这样的话,能得到80分,面试官可能会继续问,还会有什么问题。这里的问题是假如low和high很大的话,low + high可能会溢出。因此我们可以这么写:

int mid = low+(high - low)>>1;

只要 low和high没有溢出,上面的mid一定不会溢出。

你觉得可以得到90分,很可惜是0分,因为当你修改代码测试的时候,可能会出现了死循环,例如原始序列是1到8,搜索3的时候就死循环了。这是为什么呢?

这是因为移位的运算符>>优先级比加减要低,所以上面的执行顺序是这样的:

(low+(high - low))>>1

很明显这不是我们预期的。解决方法也很简单,加括号就行了。所以最终的代码就是:

 public int binarySearch(int[] array, int low, int high, int target) 
        while (low <= high) 
            int mid = low + ((high - low) >> 1);
            if (array[mid] == target) 
                return mid;
             else if (array[mid] > target) 
                // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                high = mid - 1;
             else 
                // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                low = mid + 1;
            
        
        return -1;
    

这样的话,面试官就提不出什么问题了,而且上面这个优先级问题很多人只是理解,白纸写也没事,因为很多面试官也不会注意到这里会有死循环的情况。

当然这里还没有考虑元素重复的问题,基本二分查找就是这样了。

以上是关于你能写出满分的二分查找算法吗的主要内容,如果未能解决你的问题,请参考以下文章

二分查找+所有细节保姆级详解

算法:二分查找法

python算法:二分查找

二分查找--整理

二分查找,没那么简单!

算法系列之七 二分查找