二分查找题解

本文介绍了如何在单调不下降的整数序列中,通过二分查找法快速查询目标值的首次出现位置。核心思路在于利用序列的单调性,不断缩小搜索范围。在每次二分查找时,根据中间值与目标值的关系更新搜索边界。通过实例和代码解析,详细展示了二分查找的过程,并提供了完整的AC代码实现。这种方法适用于处理大量查询操作,提高了效率。
摘要由CSDN通过智能技术生成

二分就是从中割开将其分为两半,分别处理。

题目背景:给定n个单调不下降的非负整数,m次查询,每次查询给定数字在数列里第一次出现的序号,从1开始编号。

核心思路二分:由于这是一个单调的不下降序列,所以如果当前的数比要找的数k小,那么当前这个数前面的数都比这个数小所以就没有必要去判断了,而为了次数更少我们就可以直接总数列的中间开始判断,如果中间的数mid比他小,那么这个数就一定在mid—最右中间,然后在判断mid和最右的中间midmid,以此类推。

举个栗子:有a数组1 3 3 3 5 7 9 11 13 15 15;从中查询k=5;先判断中间mid为a(1+11)/2=a6比k大所以我们查询的数一定在a1——a6中,然后a1——a5的中间为mid为a(1+5)/2:a3=3,3比5小所以我们要求的一定在a4——a5中——>mid=a(4+5)/2;a4=3还是比k小——>下一个mid=a(5+5)/2=5与k相等,此时就得到我们想要的东西了。

首先刚开始的情况如图1

在这里插入图片描述

此时的mid比k大所以我们可以肯定k在L——mid之间,此时我们将R=mid-1;因为mid不等于k所以mid也不用判断了。

如图2

在这里插入图片描述

此时的mid比k小且不等于k所以我们就不用考虑mid及mid之前,所以将L=mid+1;由于此时L的位置是4,R的位置是5所以mid的位置是4.5但是由于计算机的整数会自动去掉小数点后的东西,所以mid的位置是4.

如图3在这里插入图片描述

此时mid依然比k小所以继续将L=mid+1;这样的话L和R就同时处在了k的位置上此时mid就是k。

如图4

在这里插入图片描述

这个时候L不小于R了就可以退出二分返回位置,如果该位置上的值与所查询值相等就输出位置,不相等输出-1.

注意!!只能在单调的数列中使用二分查找。

下面是代码部份

首先是单纯的二分部份

int l=0,r=n;
int mid=(l+r)/2;
while(l<r)
{
mid=(l+r)/2;//更新mid的值
if(a[mid]>=k)r=mid+1;//有的情况要加1有的情况不加1看情况决定加不加1.
else l=mid+1;
}

然后附上ac代码

#include<cstdio>
using namespace std;

int n,m,q,a[1000005];

int find(int x) //二分查找 
{
	int l=1,r=n;
	while (l<r)
	{
		int mid=l+(r-l)/2;
		if (a[mid]>=x) r=mid;
		else l=mid+1;
	}
	
	if (a[l]==x) return l; //找都了就输出他的位置 
	else return -1; // 没找到输出-1 
}

int main()
{
	scanf("%d %d",&n,&m); //读入 
	
	for (int i=1 ; i<=n ; i++)
	    scanf("%d",&a[i]); //还是读入 
	
	for (int i=1 ; i<=m ; i++)
	{
		scanf("%d",&q);
		int ans=find(q); //看看查找的结果 
		printf("%d ",ans); //输出 
	}
	
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值