二分查找无废话版总结

511 阅读4分钟

在这里为大家整理一下二分查找算法的核心思想,更多的是给出一些问题供读者思考,所以就不花大段篇幅介绍二分查找算法的细节。相信经过读者的 不断练习和思考、总结 ,理解了二分查找算法的 思想 以后,再应对二分查找的问题就能轻松解决了。

主要的内容来自于「力扣」第 287 题(寻找重复数)回答网友的评论。

二分查找的核心思想

二分查找的核心思想是「减治」,即「不断缩小问题规模」。

二分查找的两种思路

  • 思路 1:while(left <= right) 这种写法在循环体内部直接查找元素,退出循环的时候 leftright 不重合,区间 [left, right] 是空区间;
  • 思路 2:while(left < right) 这种写法在循环体内部一直在排除元素;退出循环的时候 leftright 重合,区间 [left, right] 收缩成 11 个元素。

以下两个动画分别展示了这两种思路的执行流程。

第 2 种思路可以归纳为「左右边界向中间走,两边夹,最后剩下的一个数,有可能就是目标元素」,这种思路在解决复杂问题的时候,可以使得思考的过程变得简单。

我们在这里就不介绍代码该怎么写了。我的建议是大家可以基于上面提到的两种思路,先自己思考代码该怎么写,面对一个问题,两种思路选择其中一种自己 能够清晰表述 出来的思路进行实现就可以了,不用苛求用两种思路都写出来。

代码的细节部分,还有一些坑和注意事项,不管是我写的题解,还是其他朋友的介绍,都不缺乏这样的内容,比起看他人的介绍,更关键的是自己去练习、思考,才能 深刻理解二分查找算法设计的思想

二分查找的三种题型

  • 在一个数组里查找一个数,简称为「二分下标」;
  • 在一个有范围的整数里查找一个整数,简称为「二分答案」;
  • 通过一个变量与另一个变量的相关关系,进而确定目标变量的值,统称为「复杂问题」。

这部分详细的介绍和例题也请见「力扣」第 35 题题解。

为什么总是写不对「二分查找」

我认为:二分查找不难,只是在考察我们是否细心,如果面试中遇到,是一定要拿下的。弄不清楚边界条件,不太认真,也 有可能在背模板,没有搞清楚思想和里面非常细节的地方。

  • 我的经验是把区间定义成为:左闭右闭区间,左右边界理应是无差别的,弄成左闭右开,反而增加了 解决问题的的复杂程度
  • 明确 int = left + (right - left) / 2 这里除以 22 是下取整(想一想上取整可以吗,什么时候需要上取整,为什么是除以 22 ,其它整数行不行);
  • 明确 while(left <= right)while(left < right) 这两种写法在思路上有本质差别,里面的逻辑该怎么写,应该做到心中有数;
  • 始终在思考下一轮搜索区间是什么,这一点是上面所说的:「始终将区间认为是 左闭右闭 区间」,这样就能帮助我们搞清楚边界是不是能取到,等于、+1+11-1 之类的细节,因为即使定义成左闭右开区间 [left, right) 也一定对应一个等价的左闭右闭区间 [left, right - 1]
  • 思考清楚每一行代码背后的语义是什么,保证语义上清晰,也是写对代码,减少 bug 的一个非常有效的方法;
  • 理解算法思想的一个很重要的方法是 调试,它不是什么很高超的技巧,就是把变量的值打印出来看一下,相信就能解决为什么写出的代码会造成死循环的问题,并得出解决方案。

在下面的视频题解里,我都非常具体地讲解了我是怎么分析和做二分查找问题的。

说明:微信里不能展示链接,可以在「力扣」这个网站的题解区看到我的讲解视频,位置都比较显眼,很好找。

二分查找的详细细节,可以查看我在 「力扣」第 35 题的题解:《用减治思想写二分查找问题、几种模板写法的介绍与比较》。

这里强调一点:称为「模板」只是一个名词,我在讲解的时候会重在讲解算法思想,所以学习的建议是 理解思想 ,也就是一开始提到的两个思路(循环体里直接查找元素、循环体里排除元素)。


这就是今天和大家分享的内容,感谢大家的收看。