基础算法学习——整数二分

题目描述

题目源自ACWing题库

二分法思想

前提:数据是有序的
比较这组数据中间的那个数与要查找的数的大小,根据比较结果缩小比较区间,当比较区间为1时即锁定我们要查找的数

题解

第一步:确定要查找的数(该数在数组中可能有多个)是左边界(第一个x)还是右边界(第二个x)
在这里插入图片描述

第二步:选对应的二分模板
1)查找左边界
比较区间的中间值与x的大小,若中间值大于等于x则将r=mid区间缩小一半,否则l=mid+1,循环上面步骤,直到l=r。此时区间长度为1,覆盖的那唯一一个数就是我们要查找的x。
对应模板:

while(l<r)
    {
        int mid = l+r >> 1;
        if(q[mid]>=x) r = mid;
        else l = mid+1;
    }

2)查找右边界
右边界x左边的数全小于等于x,则此时判断条件为q[mid]<=x

注意:此时mid=l+r+1>>1,因为若mid任为区间一半,则会发生死循环

比较区间的中间值与x的大小,若中间值小于等于x则将l=mid区间缩小一半,否则r=mid-1,循环上面步骤,直到l=r。此时区间长度为1,覆盖的那唯一一个数就是我们要查找的右边界x
对应模板:

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

完整代码

#include<stdio.h>
#define N 100001
int bsearch_left(int l, int r, int x);
int bsearch_right(int l, int r, int x);
int q[N];
int main(void)
{
    int n,m,i,x; scanf("%d",&n); scanf("%d",&m);
    for(i=0; i<n; i++) scanf("%d",&q[i]);
    while(m--)
    {
        scanf("%d",&x);
        int l = 0, r = n-1;
        l = bsearch_left(l,r,x);
        if(q[l]!=x)
        {
            l = -1; printf("%d %d\n",l,l);
        }
        else
        {
            printf("%d ",l);
            l = 0, r= n-1;
            l = bsearch_right(l,r,x);
            printf("%d\n",l);
        }
    }
    return 0;
}
int bsearch_left(int l, int r, int x)
{
    while(l<r)
    {
        int mid = l+r >> 1;
        if(q[mid]>=x) r = mid;
        else l = mid+1;
    }
    return l;
}
int bsearch_right(int l, int r, int x)
{
    while(l<r)
    {
        int mid = l+r+1 >> 1;
        if(q[mid]<=x) l = mid;
        else r = mid-1;
    }
    return l;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值