zoukankan      html  css  js  c++  java
  • 【算法总结】二分查找续

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

  • 相关阅读:
    文件
    购物车
    session
    三级联动
    综合
    jquery弹窗插件
    Jquery
    PDO
    session cookie用法
    租房子
  • 原文地址:https://www.cnblogs.com/Atanisi/p/8047720.html
Copyright © 2011-2022 走看看