• 二分总结


    虽然二分是一个很基础的算法,可是其重要性是十分显然的

    二分的思想也可以扩展到许多更高级的算法和数据结构上

    所以有必要学好二分的本质和精髓,掌握二分的许多细节

    我们先来看一个最最基本的例子:

    给一个排好序的长为n的序列

    求出大于等于k的第一个位置

    很显然,我们并不需要一个一个查找,我们假设要求的位置在区间[L,R]中

    取中点mid,若中点处的值大于或等于k,那么答案一定[L,mid]这个区间内

    注意到mid是有可能成为答案的,所以划分区间时要注意

    但如果mid处的值小于k,那么mid一定不会成为答案,所以答案区间在[mid+1,R]中

    在划分区间时,我们发现有[L,mid]这个区间,所以mid的值不能与R相等,不然可能死循环

    所以我们去mid时要向下取整,避免这种现象

        while(r>l)
        {
            int mid=l+r>>1;
            if(a[mid]>=k) r=mid;
            else l=mid+1;
        }

    将问题转换一下

    给一个排好序的长为n的序列

    求出小于等于k的第一个位置

    这与上面的问题其实也是类似的

    将区间划分为[L,mid],[mid+1,R]两个部分

    只不过当a[mid]小于等于k时,可能的答案区间为[mid,R]

    而当a[mid]大于k时可能的答案区间为[L,mid-1]

    这样的话为了避免死循环,我们就得将mid向上取整

    即mid=(l+r+1)/2;

        while(r>l)
        {
            int mid=(l+r+1)>>1;
            if(a[mid]<=k) l=mid;
            else r=mid-1;
        }

    我们来深入研究二分的本质,发现二分降低复杂度的根本原因其实是因为答案的单调性

    那么,其实所有具有单调性的答案其实都是可以通过二分来查找的

    我们也称答案具有二分性

    对于具有二分性的答案,往往在有求满足条件最小或最大的值时,就可以利用二分来求解了

  • 相关阅读:
    android:background背景图片被拉伸问题
    面试积累(String和StringBuffer, StringBuilder的理解)
    面试积累(冒泡排序和选择排序)
    面试积累(java的内存分析)
    面试积累(java配置环境变量)
    异常积累(SQLException)
    【linux】fdisk磁盘分区
    【走马观花】十一月十八日通州雨
    【linux】CentOS查看硬件信息
    【linux】go安装及配置
  • 原文地址:https://www.cnblogs.com/logeadd/p/9314537.html
Copyright © 2020-2023  润新知