码迷,mamicode.com
首页 > 编程语言 > 详细

【算法总结】二分查找续

时间:2017-12-16 22:10:10      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:避免   最大   注意   不能   highlight   log   cpp   problem   没有   

  之前谈的都是查找某个特定值,这里主要是谈论最小化最大值和最大化最小值问题。二分问题最容易搞错的就是终止条件,区间形式,返回lb还是ub或者需不需要再加减一。这里列出了模板

一:整型数二分

1.最小化最大值问题

形式一:(ub - lb) > 1   区间为 (lb, ub]  结果为 ub

while (ub - lb > 1) {
    int mid = lb + (ub - lb) / 2;
    if (C(mid)) 
        ub = mid;
    else
        lb = mid;
}
// 终止循环时 ub == lb + 1

 

形式二: (ub - lb) > 0  区间为 [lb, ub]  结果为 ub

while (ub - lb > 0) {
    int mid = lb + (ub - lb) / 2;
    if (C(mid)) 
        ub = mid;
    else
        lb = mid + 1;
}
// 终止循环时 ub == lb

  

2.最大化最小值问题

形式一:(ub - lb) > 1   区间为 [lb, ub)  结果为 lb

while (ub - lb > 1) {
    int mid = lb + (ub - lb) / 2;
    if (C(mid)) 
        ub = mid;
    else
        lb = mid;
}
// 终止循环时 ub == lb + 1

 

形式二: (ub - lb) > 0  区间为 [lb, ub]  结果为 lb

while (ub - lb > 0) {
    int mid = lb + (ub - lb + 1) / 2;
    if (C(mid)) 
        lb = mid;
    else
        ub = mid - 1;
}
// 终止循环时 ub == lb

  最小化最大值通过维护ub的位置,最大化最小值通过维护lb的位置。

  死循环的核心点在于mid的取值方式:mid = lb + (ub - lb) /2,如果某一时刻 ub == lb + 1,那么由于mid的向下取整,会导致 mid = lb; 假如 if 语句导致 lb = mid 发生,那么就会进入死循环,mid = lb,接着 lb = mid。同样的 mid = lb + (ub - lb + 1) / 2; 如果有 ub = mid操作,也有可能进入死循环。但是ub - lb > 1的终止条件会使得此情况不再发生,原因在于当ub == lb + 1时,由于不满足循环条件循环退出,也就不存在mid = lb或者 mid = ub的操作了。

  当区间为闭区间,防止进入死循环的方法就是不能使mid == lb && mid == ub成立

1)最小化最大值 mid 向下取整(维护ub)

  如果 if 条件成立,需要维护ub,令ub = mid; 如果不成立则令lb = mid + 1;因为mid向下取整只可能取到lb,为避免死循环就必须使lb = mid + 1;且因为我们要求的是最小化满足条件的值,既然mid不满足循环条件,也就无需考虑此值了。

2)最大化最小值 mid 向上取整(维护lb)

  如果 if 条件成立,需要维护b,令lb = mid; 如果不成立则令ub = mid - 1;因为mid向上取整只可能取到ub,为避免死循环就必须使ub = mid - 1;且因为我们要求的是最大化满足条件的值,既然mid不满足循环条件,也就无需考虑此值了。

    

二:浮点数二分

浮点数二分就通常没有所谓的边界问题了

形式一:

for (int i = 0; i < 100; i++) {
    double mid = lb + (ub - lb) / 2;
    if (C(mid)) 
        ub = m; // lb = m;  according to problem
    else
        lb = m; // ub = m;  according to problem
}

  100次的循环精度可达10e-30

形式二:

while (ub - lb > eps) {
    double mid = lb + (ub - lb) / 2;
    if (C(mid)) 
        ub = m; // lb = m;  according to problem
    else
        lb = m; // lb = m;  according to problem
}

  eps可根据实际情况来设定,需要注意的是eps如果太小,因为浮点数机器实现的原因,可能会导致死循环。  

 

【算法总结】二分查找续

标签:避免   最大   注意   不能   highlight   log   cpp   problem   没有   

原文地址:http://www.cnblogs.com/Atanisi/p/8047720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!