二分查找[整数二分]

news2025/1/11 11:43:02

引例

不知道你有没有玩过猜数字游戏,在0到100之间随机选取一个数,让你猜是几,比如这个数是67,如果你猜了50,就会提示你小了,那么你就会去51到100之间猜,你猜了75,就会提示你大了,你就会去51到74之间去猜,就这样一直猜,数字可取的区间越来越小,用不了多久就可以猜出.当你每次都将区间减半,就是二分了

二分的本质

对于二分查找的本质不是单调性,有单调性的题目必然可以二分,可以二分的题目不一定非得有单调性,例如上方引例就是有单调性.

那么二分的本质是什么呢?在一个区间中满足某种性质的元素都在右边,不满足的都在左边,就可以使用二分.每次二分都会将答案所在的要求的区间减少一半(注:这两个区间没有交界)

以下是二分的模版,先看过再理解

int bsearch_1(int l, int r)
{
	int mid = (l + r) >> 1;

	while (l < r)
	{
		if (check(mid)) // check()判断mid是否满足某种性质
		{
			r = mid;
		}
		else
		{
			l = mid + 1;
		}
	}
	return 1;
}
int bsearch_2(int l, int r)
{
	int mid = (l + r + 1) >> 1;
	while (l < r)
	{
		if (check(mid)) // check()判断mid是否满足某种性质
		{
			l = mid;
		}
		else
		{
			r = mid - 1;
		}
	}
	return 1;
}

我们可以类比猜数字游戏

其中第一个模版就是判断你猜的数字是否小于x,如果为真,区间的r不变,l为你猜的那个数字加一,否则区间的l不变,r为你猜的那个数字

第二个模版就是判断你猜的数字是否大于x(x是选取的数),如果为真(大于x),区间的l不变,r为你猜的这个数字减一,否则区间的r不变,l为你猜的那个数字

数的范围(二分查找应用) 

给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。

对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。

如果数组中不存在该元素,则返回“-1 -1”。

输入格式
第一行包含整数n和q,表示数组长度和询问个数。

第二行包含n个整数(均在1~10000范围内),表示完整数组。

接下来q行,每行包含一个整数k,表示一个询问元素。

输出格式
共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回“-1 -1”。

数据范围
1≤n≤1000001≤n≤100000
1≤q≤100001≤q≤10000
1≤k≤100001≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1

分析

我们来看这题怎么样可以将二分的知识套进去呢,首先处理的这个问题是单调递增的,所以一定可以使用二分查找,题目要求我们找到一个数字(可能有多个,也可能没有)在数组中的起始位置和终止位置,那么可以查找第一个大于等于这个数的位置,查找第一个小于等于这个数的位置,一般来说这个就是他的起始和终止位置,但是有可能这个数在数组中不存在,所以还得判断这个数是否与数组[起始位置]或者数组[终止位置]相等,如果不相等,则说明数组中不存在这个数

来人,上代码! 

const int N = 100010;
int p[N];
int n;
int q; // q次询问
int k; // 询问元素
int main(void)
{
	scanf("%d%d", &n, &q);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &p[i]);
	}
	while (q--)
	{
		scanf("%d", &k);

		int l = 0, r = n - 1;
		while (l < r)
		{
			int mid = (l + r) / 2;
			if (p[mid] >= k) // 找第一个大于等于k的数
			{
				r = mid;
			}
			else
			{
				l = mid + 1;
			}
		}

		if (p[l] != k) 
		{
			printf("-1 -1\n");
		}
		else
		{
			printf("%d ", l);

			int l = 0, r = n - 1; 
			while (l < r)  // 找第一个小于等于k的数
			{
				mid = (l + r + 1) / 2; 
				if (p[mid] <= k)
				{
					l = mid;
				}
				else
				{
					r = mid - 1;
				}
			}
			printf("%d\n", r);
		}

	}


	return 0;
}

运行结果

完美运行,还有一件事,数组是单调递增的!! 题目已经说明了,在输入数据的时候别出错

边界问题

为啥在代码中,第二次循环中mid=(l+r+1)/2,而不是mid=(l+r)/2,因为这是整数除法,会向下取整,所以不加1的话求的是中间或者中间偏左的下标,加1则求的是中间或者中间偏右的下标,那具体有什么影响?当自己写代码的时候,你可以将错就错,看看写了mid=(l+r)/2会发生什么,当代码进行到l=r-1时,此时l和r的区间内只有两个数,mid求的是l的下标(中间偏左),如果满足条件,那么l会更新成mid,而mid就是l,所以会死循环,如果不满足条件,r会更新成mid-1,也就是l-1,可能数组中明明有元素满足,可是却不能得到正确的答案,现在你应该明白了第二次循环的mid为什么要加一

记住,每次你选取的区间一定要包含答案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1002634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot如何实现热部署

热部署是软件开发中一个非常有用的功能&#xff0c;它允许我们在不重新启动整个应用的情况下&#xff0c;依旧能够使我们修改的代码生效。 现在Java Web 开发应该都是使用的 SpringBoot&#xff0c;那么本篇文章就来介绍SpringBoot 如何实现热部署&#xff1f; 1、热部署的优点…

如何提取视频中的音频?几个步骤轻松提取

在现今社交媒体的风靡下&#xff0c;许多人都会使用手机录制视频来记录生活中的美好瞬间。有时候&#xff0c;我们也会想要提取视频中的音频&#xff0c;例如将自己的演讲录音分发给听众。本文将会介绍如何在手机上提取视频中的音频以及需要注意的事项。 使用应用程序 首先&am…

Linux Debian12使用git将本地项目上传到码云(gitee)远程仓库

一、注册码云gitee账号 这个可以参考其他教程&#xff0c;本文不做介绍。 gitee官网&#xff1a;https://gitee.com/ 二、Linux Debian12安装git 如果Linux系统没有安装git&#xff0c;可以使用下面命令安装git sudo apt install git 三、gitee新建仓库 我这只做测试&…

实现分别在Linux、Docker、Kubernetes上安装部署Mysql、Redis、Nginx软件

目录 实现目的&#xff1a; Linux上一键安装Mysql、Nginx、Redis软件 一键安装Mysql脚本 一键安装Redis脚本 一键安装Nginx脚本 docker上安装部署Mysql、Nginx、Redis容器 Kubernetes上安装部署Mysql、Nginx、Redis的Pod和通过Service发布 创建Pod生成容器 使用Servic…

时间序列论文-聚类和异常检测(二)

同样摘自知乎的回答&#xff1a;https://www.zhihu.com/question/29507442/answer/1212624591?utm_id0 正巧之前做过时间序列 的异常检测项目&#xff0c;这里介绍几种尝试过的方法&#xff0c;也算是抛砖引玉 吧&#xff0c;欢迎大家讨论交流~ 背景与定义 时间序列异常 检测…

c++实现数据结构栈和队列

1、栈 头文件 #ifndef ZHAN_H #define ZHAN_H#define MAX 8 #include <iostream> using namespace std;class Shu {int datatype; //入栈的数据int *arr; //栈的数组int top; //记录栈顶元素的下标public://构造函数Shu();//析构函数~Shu();//判断空int stack_empty…

COSCon'23 Call for Speakers

一年一度的开源盛会&#xff0c;COSCon23 第八届中国开源年会&#xff0c;将于10月28~29日&#xff0c;在四川成都市高新区菁蓉汇召开&#xff01; The yearly open source event, COSCon23 8th Annual China Open Source Conference, will be taken place on 28th~29th Octobe…

【编码魔法师系列_构建型1.1】简单工厂模式(Static Factory)

学会设计模式&#xff0c;你就可以像拥有魔法一样&#xff0c;在开发过程中解决一些复杂的问题。设计模式是由经验丰富的开发者们&#xff08;GoF&#xff09;凝聚出来的最佳实践&#xff0c;可以提高代码的可读性、可维护性和可重用性&#xff0c;从而让我们的开发效率更高。通…

让照片动起来的软件,轻松制作照片动效

随着社交媒体的日益普及&#xff0c;我们对于照片的要求也越来越高。普通的照片已经不能满足我们的需求&#xff0c;我们希望照片更加生动有趣。照片动效便应运而生&#xff0c;它可以让照片动起来&#xff0c;吸引更多的注意力&#xff0c;让照片更加生动有趣。 照片动效制作起…

软件验收测试

1. 服务流程 验收测试 2. 服务内容 测试过程中&#xff0c;根据合同要求制定测试方案&#xff0c;验证工程项目是否满足用户需求&#xff0c;软件质量特性是否达到系统的要求。 3. 周期 10-15个工作日 4. 报告用途 可作为进行地方、省级、国家、部委项目的验收&#xff0…

Java-华为真题-预定酒店

需求&#xff1a; 放暑假了&#xff0c;小王决定到某旅游景点游玩&#xff0c;他在网上搜索到了各种价位的酒店&#xff08;长度为n的数组A&#xff09;&#xff0c;他的心理价位是x元&#xff0c;请帮他筛选出k个最接近x元的酒店&#xff08;n>k>0&#xff09;&#xff…

JavaScript中的Generator函数及其使用方式

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Generator函数⭐ 创建Generator函数⭐ 调用Generator函数⭐ Generator函数的应用1. 异步编程2. 生成器&#xff08;Generator&#xff09; ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧…

L1-002 打印沙漏分数 20

L1-002 打印沙漏 分数 20 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”&#xff0c;要求按下列格式打印 ************ *****所谓“沙漏形状”&#xff0c;是指每行输出奇数个符号&#xff1b;各行符…

23年11月PMP考试如何报名?如何备考?(含备考干货)

总分为4个步骤&#xff1a;英文报名--审核【抽中后快递材料审核】--中文报名--在线支付费用 一、PMP英文报名&#xff1a; 英文报名时间无限制&#xff0c;但有一年的有效期&#xff0c;所以大家尽量提前报名 二、审核&#xff1a; PMI网站对你英文报名的材料进行审核&…

Java——》synchronized锁升级

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

Win11共享文件夹怎么设置

当我们在使用Win11的过程中有时会因为一些操作需要共享文件夹&#xff0c;那么Win11系统该如何设置共享文件夹呢&#xff0c;下面小编就给大家详细介绍一下Win11设置共享文件夹的方法&#xff0c;有需要的小伙伴快来和小编一起看看吧。 Win11设置共享文件夹的方法&#xff1a;…

MySQL——无法打开MySQL8.0软件安装包或者安装过程中失败,如何解决?

在运行MySQL8.0软件安装包之前&#xff0c;用户需要确保系统中已经安装了.Net Framework相关软件&#xff0c;如果缺少此软件&#xff0c;将不能正常地安装MySQL8.0软件。 解决方案&#xff1a;到这个地址 https://www.microsoft.com/en-us/download/details.aspx?id42642…

如何查询成绩或工资

为什么每次查询成绩或者工资的时候都觉得麻烦又耗时呢&#xff1f;在过去&#xff0c;我们可能需要去学校或公司的相关部门&#xff0c;填写繁琐的表格&#xff0c;然后等待工作人员进行查询和处理。这不仅浪费了我们宝贵的时间&#xff0c;还可能出现查询结果不准确或者遗漏的…

华为OD机试 - 快速人名查找 - 深度优先搜索dfs(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

天津大数据培训学校 大数据可从事的行业

大数据行业近年来呈现出爆炸式的增长态势&#xff0c;各行各业都越来越依赖数据来指导业务决策和创新发展&#xff0c;因此&#xff0c;大数据专业人才的需求也随之增长。这种行业需求的增长为大数据就业提供了良好的机会&#xff0c;尤其是对于具备相关技能和知识的人来说。 …