首页 > 其他 > 详细

递增整数序列的二分详解

时间:2017-01-05 13:33:46      阅读:249      评论:0      收藏:0      [点我收藏+]

二分搜索是一种时间复杂为log2n的算法,可以用于单调函数求根和单调序列查询的有效算法,即使数列长度高达10^9 也只需二分31次,查询速度接近常数,同时二分思想是一种很基础很重要的思想希望同学们都能掌握;

单调数列(单调递增)通用二分模板

简洁版

 

技术分享

完全版

技术分享

start_index =0end_index=len-1时,功能和简洁版一样;

 

1.

 

 

为啥不能写下面这句

 

ifmid==n

 

return mid

 

因为有时候会有

 

这样的一种数列

 

1 2 2 2 2 3

 

这个是非严格单调序列,如果叫你寻找2第一次出现的位置显然会出现错误

 

所以上面那个写法是不行的;

 

2.

 

为啥不写left=mid+1right=mid-1

 

因为有些情况下会不能用

 

比如在数列

 

a[]={0 1 3 4,5}

 

找大于2的第一个位置

 

当你right=4left=0;

 

mid=2A[mid]>2 所以 若r=mid-1=1你就错过去了,除非你用if判断一下,但那样就太冗长难看了;

 

3.

 

为啥不能写

 

while(left=right)

 

因为上面的原因我们没用 left=mid+1right=mid-1

 

而是left=mid,right=mid

 

a[]={0,1,3,4};

 

则找2的位置时会死循环

 

因为 left=1right=2

 

mid=(left+right)/2=1

 

a[mid]<2;

 

所以left=mid=1

 

结果left还是等于1right还是等于2

 

永远死循环

 

现在来解释一下上面代码的原理:

我们让left代表小于等于 x的一方

       right代表大于x的一方

我们每次判断mid是属于left还是属于right来使区间缩小一半;

leftright相遇时,即left+1=right时 分界线就在leftright中间

则从left开始往前小于等于x,right开始往后大于x

技术分享

同理其实我们也可以让

iff(mid)<x

left=mid;

else

right=mid;

这时

left代表小于x的一方

         right代表大于等于x的一方

leftright相遇时;

则从left开始往前小于x,right开始往后大于等于x

即如图所示

技术分享

 

最后我们来教点小技巧

如果我把前一种记做find_upper_bound()

 技术分享

如果我把后一种记做find_lower_bound()

技术分享

显然图观察可得 两种的二分结果分别是

x的下标上界(不包含x)和和下标上界(包含x

他们相减就是x的个数

显然若find_upper_bound(x)==find_lower_bound(x);那么就不存在x

在使用时不用写两种二分,其实由观察图可得

find_upper_bound(x-1)=find_lower_bound(x);

或者find_upper_bound(x)=find_lower_bound(x+1);

所以其实写一种就行了;

这里给出对照表(前提是整数递增序列)

查询目标            find_upper_bound的用法    find_lower_bound的用法

大于x的第一个位置           find_upper_bound(x)    find_lower_bound(x+1)

x出现的第一个位置           find_upper_bound(x-1)     find_lower_bound(x)小于x的第一个位置           find_upper_bound(x-1)-1   find_lower_bound(x)-1

x出现的最后位置             find_upper_bound(x)-1     find_lower_bound(x+1)-1

习题

1.http://210.34.193.66:8080/vj/Problem.jsp?pid=2145

2.http://210.34.193.66:8080/vj/Problem.jsp?pid=1923(这题注意要先用快速排序再二分)

这里是习题1的标程

技术分享

技术分享

 

递增整数序列的二分详解

原文:http://www.cnblogs.com/qswg/p/6251887.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!