【模板】二分

二分查找是一种在有序数组中寻找元素的高效算法,其时间复杂度为O(logn)。文章介绍了二分查找的概念、时间与空间复杂度,并提供了一个迭代版本的二分查找模板。通过一个来自洛谷的例题,解释了如何利用二分查找解决实际问题,如确定公路中最大空旷指数,同时展示了如何构建check函数来验证解的可行性。
摘要由CSDN通过智能技术生成

  二分查找(英语:binary search),也称折半搜索(英语:half-interval search)、对数搜索(英语:logarithmic search),是用来在

时间复杂度

二分查找的最优时间复杂度为O(1) 

二分查找的平均时间复杂度和最坏时间复杂度均为 O(logn)。因为在二分搜索过程中,算法每次都把查询的区间减半,所以对于一个长度为 n的数组,至多会进行 O(logn)次查找。

空间复杂度

迭代版本的二分查找的空间复杂度为 O(1)。

递归(无尾调用消除)版本的二分查找的空间复杂度为 O(logn)

一个有序数组中查找某一元素的算法。

使用背景:

问题的解空间具有单调性:如果问题的解具有单调性,即满足某种特定的顺序或条件,那么通常可以使用二分法。例如,有序数组中查找某个元素、确定某个函数的最大值或最小值等。
解题的时候往往会考虑枚举答案然后检验枚举的值是否正确。若满足单调性,则满足使用二分法的条件。把这里的枚举换成二分,就变成了「二分答案」。

模板:

int l = 0,r = 10000000;
        while(l+1<r)
        {
            int mid = (l+r)/2;
            if(check(mid)) //check()函数是用来检查mid是否为可行解
                r = mid;
            else
                l = mid;
        }
//return r(最小值)
//return l(最大值)

例题: (来自洛谷)

解题思路:

首先我们要知道这个问题中的可行解是指“空旷指数”,也就是公路中的最大距离,接下来我们就应该去判断可行解的边界单调性,边界很好知道,右边界是整条公路的长度,左边界是0。又因为对于任一给定的公路,假设为输入样例#1的情况,公路长度为101,我们可以知道在解空间(0,101)中,大于等于51的解均为可行解,而小于51的解均不可行,因为此时插一个路标不可能使空旷指数小于51,因为本题要求的是最小可行解,所以这个分界点51就是最优解。

我们可以知道在51左边的空旷指数,如果要满足,会需要比1更多的增设路标,而题目中提供了1个,因此我们将需要的增设路标当成y,空旷指数为x,这个函数是单调递减的,同时,我们根据题目给出的增设数量1,可以将解分为可行解不可行解。

推广到更一般的情况,对于任意给定的公路长度L,路标N,最大增设K,我们可以知道

 显而易见我们可以通过二分答案然后检验mid的值是否为可行解来不断二分最后求得最优解。

所以我们还需要一个check()函数来判断二分出来的值是不是可行解,那怎么判断对于一个空旷指数x它满不满足可行解的要求呢?我们知道,如果对道路增设count个路标之后,使得x比道路上每个相邻路标都大,如果添加的路标数小于提供的路标数,则x是可行解,反之,则不是。

代码:

 arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = s.nextInt();
        }
        int l = 0,r = arr[N-1]+1;
        while(l+1<r)
        {
            int mid = (l+r)/2;
            if(check(mid,M))
                r = mid;
            else
                l = mid;
        }
        System.out.println(r);

static boolean check(int mid,int M)
{
    int count = 0;
    int sum = 0;
    int cha = arr[0];
    for (int i = 1 ; i < arr.length;) {
        sum = arr[i]-cha;
       if( sum > mid)
       {
           cha = cha + mid;
           count++;
       }
       else {
           cha = arr[i];
           i++;
       }
    }
    return count<=M;

}

注意:如果N=2,M=0,最优解为边界L,因此r应该取L+1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值