二分查找以及变形

2017-10-13  本文已影响0人  米耳

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

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这个条件,会出现什么情况。其实这个,经过实验,也是完全可以查找的,并且是完全闭区间的,但是需要多填一句代码。因为前面第一种情况已经实现了,所以没有必要研究这个,尽管使用上面的两种代码。


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

上一篇下一篇

猜你喜欢

热点阅读