【算法总结】二分查找续

  之前谈的都是查找某个特定值,这里主要是谈论最小化最大值和最大化最小值问题。二分问题最容易搞错的就是终止条件,区间形式,返回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如果太小,因为浮点数机器实现的原因,可能会导致死循环。  

 

posted @ 2017-12-16 21:22  Vincent丶丶  阅读(439)  评论(0编辑  收藏  举报