【二分查找】数的范围

news2024/9/22 15:33:17

数的范围

  • 思路
  • 二分查找
    • 左边界
    • 右边界
  • 代码实现

思路

在这里插入图片描述
题目主要的意思在一个升序也就是有序的数组中 找到一段相同数组的起始位置和最终位置 也就是查找两个数的问题

题目给的是升序数列让人很容易想到二分查找来查找两个数

二分查找

我们此时的问题就转化为查找到这段序列的起始位置和终止位置 我们可以用二分查找的方式

左边界

我们可以先找这段序列的左边界

例如下面这段序列

在这里插入图片描述
我们要找到箭头指向的这个数的位置

我们要设置两个标记来标记每一次二分的左右边界
第一次二分定义 (l = 0 r = n-1) n为序列的长度

在设置一个 mid 变量来标记序列中间位置

每次二分检查 mid 和 我们要找的这个数的大小关系
直到l >= r此时就找到了左边界

int left_bound(int l, int r) {
    while (l < r) {
        int mid = l + r >> 1;//求中间值
        if (q[mid] >= k) r = mid;//更新有边界
        else l = mid + 1;//更新左边界
    }
    return l;
}

我们在这里要尤其注意边界问题 因为这一段序列中有重复数据

在查找左边界时 如果 q[mid]>=k 条件成立 说明左边界点不在右半部分 此时要更新右边界的值
但是存在这个点就是我们要找的点的情况 此时mid点就不可以跳过 在更新边界点时就要保留mid点 就是 r = mid

但是如果 q[mid]>=k条件不成立 这个时候说明左边节点 在右半部分 此时要更新左半部分
此时这个点不可能是我们要找的点 因为这个点必小于k 所以将l更新为mid+1跳过这个点

右边界

然后来找这段数的右边界
在这里插入图片描述

还是这段序列 此时我们要找的是箭头指向的这个数据 如果理解了找左边界的情况 这个情况也类似

还是
我们要找到箭头指向的这个数的位置
我们要设置两个标记来标记每一次二分的左右边界
第一次二分定义 (l = 0 r = n-1) n为序列的长度
在设置一个 mid 变量来标记序列中间位置

每次二分检查 mid 和 我们要找的这个数的大小关系
直到l >= r此时就找到了右边界

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

还是和找左边界一样的考虑方法

在查找右边界时 如果 q[mid] <= k 条件成立 说明右边界点不在左半部分 此时要更新左边界的值 但是存在q[mid] = k 的情况 所以可能会出现mid位置正好是我们要的右边界 所以此时 保留mid位置的值 l = mid

如果q[mid] <= k条件不成立 说明右边界点不在右半部分 此时要更新右边界的值 由于此时不可能存在q[mid] = k 的情况出现 所以mid位置的值不需要保存 r = mid - 1

注意再求右边界的时候为什么 mid = (l + r + 1) / 2
我们考虑这种情况 在求右边界时 右边界恰好等于 l + 1 的情况 此时mid 如果等于(r + l)/2 则带入 r = l +1则有 mid = (l + l + 1) / 2 = l 此时q[mid] <= k 成立 将mid值赋给l
我们发现在一次二分后 我们的区间还是[l,r] 并没有发生改变

但是我们+1后 mid = (l + l + 1 + 1) / 2 = l + 1 此时 mid指向的值恰好为右边界 满足q[mid] <= k 条件 将此时 l = mid = l + 1 = r 区间更新为 [r, r]就没有问题

代码实现

# include<iostream>
using namespace std;

const int N = 100010;
int q[N];
int n, m;

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &q[i]);
	}
	while (m--)
	{
		int k = 0;
		scanf("%d", &k);
		int l = 0, r = n - 1;
		while (l < r)
		{
			int mid = l + r >> 1;//求mid
			if (q[mid] >= k)//找左边界
				r = mid;
			else
				l = mid + 1;
		}
		if (q[l] != k)//找不到左边界 说明没有这个数据 返回 -1
			printf("-1 -1\n");
		else
		{
			printf("%d ", l);//输出左边界
			int l = 0, r = n - 1;
			while (l < r)//找右边界
			{
				int mid = l + r + 1 >> 1;
				if (q[mid] <= k)
					l = mid;
				else
					r = mid - 1;
			}
			printf("%d\n", l);//输出右边界
		}
	}

	return 0;
}

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

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

相关文章

Python中变量的作用域精讲

文章目录前言一、局部变量二、全局变量前言 变量的作用域是指程序代码能够访问该变量的区域&#xff0c;如果超出该区域&#xff0c;再访问时就会出现错误。在程序中&#xff0c;一般会根据变量的 “有效范围” 将变量分为 “全局变量” 和 “局部变量”。 一、局部变量 局部变…

Linux——进程间通信1

目录 进程间通信目的 进程间通信标准 管道 匿名管道 管道实现进程间通信 管道的特点 进程池 ProcessPool.cc Task.hpp 习题 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件…

前端的浮点数计算问题

加 //加 export const add (num1, num2) > {var r1, r2, m, ctry {r1 num1.toString().split(.)[1].length} catch (e) {r1 0}try {r2 num2.toString().split(.)[1].length} catch (e) {r2 0}c Math.abs(r1 - r2)m Math.pow(10, Math.max(r1, r2))if (c > 0) {va…

Vue3通透教程【七】生命周期函数

文章目录&#x1f31f; 写在前面&#x1f31f; 生命周期钩子函数&#x1f31f; 组合式API生命周期&#x1f31f; 写在最后&#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 Vue3 的相关技术文章&am…

性能优化之前端项目性能优化的几种方案

加载优化&#xff0c;减少http请求一个完整的 HTTP 请求需要经历 DNS 查找&#xff0c;TCP 握手&#xff0c;浏览器发出 HTTP 请求&#xff0c;服务器接收请求&#xff0c;服务器处理请求并发回响应&#xff0c;浏览器接收响应等过程。Queueing: 在请求队列中的时间。Stalled: …

5.1 STM32学习 中断系统和EXTI外部中断

中断系统中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行。中断优先级&#xff1a;当…

框架篇-面试题6-说一下Vue2与Vue3的钩子函数

Vue钩子函数是在Vue实例从创建到销毁的过程中自动执行的函数&#xff08;在特定的阶段,能够自动自执行的函数&#xff09;钩子函数用来描述一个组件从引入(创建)到退出(销毁)的全过程中的某个过程Vue2生命周期钩子函数整个过程称为生命周期Vue钩子函数按照组件生命周期的过程分…

作为一名程序员少不了的软件

写在前面的话 就现今我自己接触的项目而言&#xff0c;我发现对于一名程序员来说有些软件是真的必不可少的&#xff0c;防止下次换电脑或者要换操作系统的时候用&#xff0c;特此记录一下。 一、最常使用的&#xff0c;JetBrain全家桶&#xff08;idea、pycharm、webstorm&…

【办公类-16-06-02】“2022下学期 总园活动室(沙水+建构)排班表(两周一次沙水)”(python 排班表系列)

作品展示&#xff1a;背景需求&#xff1a;上一篇批量制作了“7天轮回14班沙水每周固定建构”的活动室内排班表。一、时段冲突&#xff0c;调整单双周。保教主任抽空检查后&#xff0c;提到&#xff1a;“一个班、上午、下午都有自主游戏&#xff08;沙水、建构、表演、角色&am…

金三银四、金九银十 面试宝典 JAVASE八股文面试题 超级无敌全的面试题汇总(接近3万字的面试题,让你的JAVA语法基础无可挑剔)

JavaSE八股文 - 面试宝典 一个合格的 计算机打工人 &#xff0c;收藏夹里必须有一份 JAVA八股文面试题 &#xff0c;特别是即将找工作的计算机人&#xff0c;希望本篇博客对你有帮助&#xff01; 本文参考了诸多大佬的面试题帖子&#xff0c;ps&#xff1a;白大锅、哪吒、英雄…

从Linux内核中学习高级C语言宏技巧

Linux内核可谓是集C语言大成者&#xff0c;从中我们可以学到非常多的技巧&#xff0c;本文来学习一下宏技巧&#xff0c;文章有点长&#xff0c;但耐心看完后C语言level直接飙升。 本文出自&#xff1a;大叔的嵌入式小站&#xff0c;一个简单的嵌入式/单片机学习、交流小站 从…

机器看世界

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

为什么红黑树如此受欢迎

平衡二叉查找树有很多&#xff0c;但是我们一提到平衡二叉查找树&#xff0c;常提及的就是红黑树&#xff0c;它的“出镜率”甚至要高于平衡二叉查找树。 红黑树是一种相对平衡的二叉查找树&#xff0c;不符合严格意义上平衡二叉查找树的定义。 目录 红黑树的插入 红黑树的验…

SAP ABAP WebService

第一步&#xff1a;SE37 创建一个远程函数&#xff08;Remote Function Module&#xff09;注意该函数需要将Remote Enable开启第二步&#xff1a;创建WebService首先&#xff1a;SE37 打开需要关联的函数在菜单 Utilities->More Utilities->Create Web Service->From…

二 Go的基本语法

1. 基本类型 boolstringint、int8、int16、int32、int64uint、uint8、uint16、uint32、uint64、uintptrbyte // uint8 的别名rune // int32 的别名 代表一个 Unicode 码float32、float64complex64、complex128 2. 三种声明变量 2.1 标准格式 var name type 其中&#xff0c;…

MyBatis-Plus联表查询的短板,该如何解决呢

mybatis-plus作为mybatis的增强工具&#xff0c;它的出现极大的简化了开发中的数据库操作&#xff0c;但是长久以来&#xff0c;它的联表查询能力一直被大家所诟病。一旦遇到left join或right join的左右连接&#xff0c;你还是得老老实实的打开xml文件&#xff0c;手写上一大段…

链表及其基本操作

1.单链表&#xff1a;1.1定义/性质&#xff1a;链表是线性表的链式存储方式。单链表通过指针线性遍历&#xff0c;删除/增加节点时间复杂度为O(1&#xff09;,访问节点时间复杂度为O(n)。单链表分为带头结点和不带头结点两种&#xff0c;带头结点是为了方便统一操作&#xff08…

数据结构:链式二叉树初阶

目录 一.链式二叉树的逻辑结构 1.链式二叉树的结点结构体定义 2.链式二叉树逻辑结构 二.链式二叉树的遍历算法 1.前序遍历 2.中序遍历 3.后序遍历 4.层序遍历(二叉树非递归遍历算法) 层序遍历概念: 层序遍历算法实现思路: 层序遍历代码实现: 三.链式二叉树遍历算…

蓝桥杯三月刷题 第六天

文章目录&#x1f4a5;前言&#x1f609;解题报告&#x1f4a5;星期计算&#x1f914;一、思路:&#x1f60e;二、代码&#xff1a;&#x1f4a5;考勤刷卡&#x1f914;一、思路:&#x1f60e;二、代码&#xff1a;&#x1f4a5;卡片&#x1f914;一、思路:&#x1f60e;二、代…

Spring SpringBoot中使用Mybatis-plusDemo1

官网:https://baomidou.com GitHub:GitHub - baomidou/mybatis-plus: An powerful enhanced toolkit of MyBatis for simplify development Gitee:mybatis-plus: mybatis 增强工具包&#xff0c;简化 CRUD 操作。 文档 http://baomidou.com低代码组件库 http://aizuda.com My…