二分查找以及变形

这个东西研究了好长时间,做下记录。
二分查找的整体结构如下:

while(lo ? hi){
  mid = (lo + hi)/2;
  if(key ? arr[mid])
     //......
  else
    //...... 
}

这片文章总结的挺好的,但是我又在解决其他问题的时候遇到不一样的套路,比如这个。主要纠结就在于第一个问号。
经过实验发现,一般我们的搜索都是在完全闭区间中进行搜索的,在这种情况下,第一个问号那里,必须写<=。但如果写成lo < hi - 1这种形式,意味着这是半开区间,在这个循环中不会找到hi这个右边界。而在之前的那种情况下是可以找到右边界的。代码如下:

情况1:lo <= hi后面的lo和hi必须要mid加一或者减一的,返回的索引是mid。完整闭区间。
情况2:lo < hi-1后面的lo和hi必须等于mid,并且返回的索引是lo。去掉了右边界。

情况1的常规代码:

while(lo <= hi){
  mid = (lo + hi)/2;
  if(x < arr[mid]) hi = mid -1 ;
  else if(x > arr[mid]) lo = mid + 1;
  else return true;
}
return false;

情况2的常规代码:

while(lo < hi-1){
  mid = (lo + hi)/2;
  if(x < arr[mid]) hi = mid;
  else lo = mid;
}
return arr[lo] == x;

在这个基础上,我还想了如果写了lo < hi这个条件,会出现什么情况。其实这个,经过实验,也是完全可以查找的,并且是完全闭区间的,但是需要多填一句代码。因为前面第一种情况已经实现了,所以没有必要研究这个,尽管使用上面的两种代码。


二分查找,看似简单,但还是很难写对。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 二分查找jdk源码 时间O(logn)空间O(1) 递归式写法: 时间和空间都是O(logn) 2. 二分插入...
    少冰三hun甜阅读 388评论 0 1
  • 原理并不复杂,[low,high]构成了潜在区间,如果中值不等于目标,则减半对应的区间。有一个问题:为什么循环条件...
    熊白白阅读 786评论 0 0
  • 最近在读< >时,了解到了很多常用的排序算法,故写一篇读书笔记记录下这些排序算法的思路和实现. 冒泡排序 冒泡排序...
    SylvanasSun阅读 712评论 0 0
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,236评论 25 708
  • 朝发临安郡兮,夕宿东阳。 苟余心糸兄弟情兮,虽路远之何伤。 怀信踯躅,忽乎吾将行兮!
    鹭岛灯泡王阅读 216评论 0 0