您的位置:首页 > 其它

夕拾算法进阶篇:37)二分答案

2017-03-17 10:54 337 查看
二分答案和二分查找类似(与其说类似,还不如说照葫芦画瓢),都是在顺序查找的基础上使用二分提高了效率。和二分查找一样(需要原序列有序),二分答案也有其前提:

(1)答案区间上下限确定,即最终答案在哪个范围是容易知道的。

(2)检验某值是否可行是个简单活,即给你个值,你能很容易的判断是不是符合题目要求。

(3)可行解满足区间单调性,即若x是可行解,则在答案区间内x+1(也可能是x-1)也可行。

二分答案通常有两种情况:最大值最小化最小值最大化(可以先不管这两个概论)。以序列a[]={1, 2, 3, 4, 5,}为例(下标从1开始),假如1 2 3 4是符合需求的,而5是不符合的。这时需要从符合需求里面选出最大的值(这里是4即最小值最大化)。通常做法是从大到小依次遍历,碰到第一个符合条件的值就直接返回。对该例来说,该方法是可行的,但如果5后面还有一连串不符合需求的数,那么该方法就不合适了。

最小值最大化

while(l<=r){//l和r表示原始序列的首末位置
mid=(l+r)/2;
if(check(mid))
l=mid+1;
else
r=mid-1;
}


下面结合上面的代码,以上面的序列为例,看下二分答案是怎么把最小值最大化的4选出来的

(1)初始时l=1,r=5。中间数mid=(l+r)/2=3,符合条件,l=mid+1=4

(2)l=4,r=5。中间数mid=4,此时符合条件,l=mid+1=5

(3)l=5,r=5。中间数mid=5,此时不符合条件,r=mid-1=4。

(4)此时l=5,r=4。r<l跳出循环,而r=4即为所求

最大值最小化

最大值最小化和上面类似,假如 2 3 4 5是符合需求的值,而1是不符合的。此时从符合需求里面选出最小的值(这里是2),只要把上面的语句变换下位置即可。

while(l<=r){//l和r表示原始序列的首末位置
mid=(l+r)/2;
if(check(mid))
r=mid-1;
else
l=mid+1;
}
下面结合上面的代码,以上面的序列为例,看下二分答案是怎么把最大值最小化的2选出来的

(1)初始时l=1,r=5。中间数mid=(l+r)/2=3,符合条件,r=mid-1=2

(2)l=1,r=2。中间数mid=1,此时不符合条件,l=mid+1=2

(3)l=2,r=2。中间数mid=2,此时合条件,r=mid-1=1。

(4)此时l=2,r=1。r<l跳出循环,而l=2即为所求
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: