基础算法-二分法

本文介绍了整数二分算法的基本概念,提供了代码模板,并强调了边界条件和不同取值方法的优缺点,以及在实际问题中的应用实例,如区间查找问题的解决方案。
摘要由CSDN通过智能技术生成

二分是一种在数学上求根的范围的方法,一般进行折半查验,最后得出其范围。在算法学习中,一般有整数二分和实数二分。在二分学习中应该注意边界以及左右区间的开闭情况,以防止出现死循环。

我们用一个例题来讲解整数二分的模板,见链接

https://www.acwing.com/problem/content/791/

我们先看二分代码的模板

while(left<right)
{
int ans;
int mid = left+(right-left)/2;
if(check(mid)){
ans = mid;
...
}
else{
'''
}
}

mid的取值有很多种写法但都有一定缺陷:

总的来说以下几种:

mid = (l+r)/2 适用于l>=0,r>=0;l+r无溢出。

mid = (l+r)>>1适用于l+r无溢出

mid =left+(right-left)/2,适用于l-r无溢出

综合来说(l+r)>>1更好

如何解决该问题,我们只要每次二分到该答案并记录下来就可以了

见代码:

#include <iostream>
using namespace std;
int n,q;
int a[1000085];
int k;
int main()
{
    cin>>n;
    cin>>q;
    for(int i=0;i<n;i++)    cin>>a[i];
    for(int i=0;i<q;i++)
    {
        cin>>k;
        int l=0,r=n-1;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(a[mid]>=k) r=mid;
            else l=mid+1;
        }
        if(a[l]!=k) cout<<"-1 -1"<<endl;
        else
        {
            cout<<l<<" ";
            int l=0,r=n-1;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if(a[mid]<=k)   l=mid;
            else r=mid-1;
        }
        cout<<l<<endl;
        }
    }
    return 0;
}

关键就在于a[mid]>=k,如果大于等于那么这个k一定在mid的左边,那么左边(l)不变,改变右边

则r=mid,反之就是l=mid+1

代码执行完后r=l,就是我们查找到答案在的位置;在这个题目中我们还需要把两边位置输出,所有就要用a[l]和k进行比较,所以我们后面还有一串代码就是将右边也进行一次二分查找;

在查找右边代码的时候我们需要注意l+r+1;+1是为了死循环,因为后面我们的r更新是-1了;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉邬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值