C++算法——二分法查找

一、二分查找算法思想和模版

1.算法思想

2.细节处理

3.模板

二、二分查找

1.链接

704. 二分查找 - 力扣(LeetCode)

2.描述

3.思路

先从最经典的题目去切入,思路就是二分查找,这里我们认为,目标值既可以看作为左部分的后端,也可以认为是右部分的前端,当然有更简单的写法,就是直接判断相等,但那个方式对二分查找这一类题目的普适性不高,作为练习,我们这里采用目标值落在左边末端的情况

4.参考代码

认为目标值在左边末端的情况

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size()-1;while(left < right){int mid = left+ (right - left + 1)/2;if(nums[mid] <= target){left = mid;}else{right = mid-1;}}if(nums[left] == target) return left;else return -1;}
};

三、在排序数组中查找元素的第⼀个和最后⼀个位置

1.链接

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

2.描述

3.思路

通过分析,这题我们需要找到target的开始和末尾,我们可以分别进行两次二分查找去分别找到开端和末尾,刚好对应着两种不同的策略和模版

target开端:我们将数据划分成 【 小于target的数 】【target开端 和大于等于target的数 】 ,此时目标数据在后半段的开端

target后端:数据划分成【小于等于target的数,target末尾】【大于target的数】,此时目标值在前半段的末端

当然也要考虑不存在target的情况,在第一次找开端时,若是没找到,则可以直接返回{-1,-1}

4.参考代码

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {//由于有空数组,做个特殊处理if(nums.size() == 0){return {-1,-1};}//寻找target开端int begin,end;int left = 0;int right = nums.size()-1;while(left < right){int mid = left + (right - left)/2;if(nums[mid] < target) left = mid + 1;else right = mid;}if(nums[left] == target) begin = left;else return {-1,-1};//寻找target末尾right = nums.size()-1;while(left < right){int mid = left + (right - left + 1)/2;if(nums[mid] <= target) left = mid;else right = mid - 1;}//由于开端已经找到,则说明一定存在target,末端也一定存在end = left;return {begin,end};}
};

四、搜索插入位置

1.链接

35. 搜索插入位置 - 力扣(LeetCode)

2.描述

3.思路

根据题意,我们不能看出使用二分查找的方法,根据题目意思,有两种情况

一种是目标值存在,那么和最简单的二分查找找目标值那题是一样的,采用哪种策略划分都可以

另一种是不存在则返回插入位置的索引,这个插入位置的索引原先是比target较大一点的值

因此我们将区域划分为【小于target的值】【大于等于target的值】,此时我们要找到目标索引就是后半部分的开端

此外,还需要考虑边界情况:

1.数组内的数全都大于target

最终,right在不断调整下,会落在0上,是满足题意的

2.数组内的数全都小于target

最终,left会落在right(最后一个位置的索引),但实际要求插入的位置是right+1的地方

所以这里做一个判断,若是最终出来的值小于target,则返回right+1(left+1)

4.参考代码

class Solution 
{
public:int searchInsert(vector<int>& nums, int target) {int left = 0;int right = nums.size()-1;while(left < right){int mid = left + (right - left)/2;if(nums[mid] < target) left = mid + 1;else right = mid; }if(nums[left] < target) left++;return left;}
};

五、x的平方根

1.链接

69. x 的平方根 - 力扣(LeetCode)

2.描述

3.思路

根据题意,我们可以认为,目标值的范围,一定会是在【1,x】区间,我们根据这个区间内每个数的平方去划分前后两个区间【平方小于等于x的数】【平方大于x的数】,我们要找的目标值落在前半部分区间的末端

考虑边界情况,目标值一定会存在,但是x从0开始,因此,我们需要对x=0时的情况做一个特殊处理

4.参考代码

class Solution {
public:int mySqrt(int x) {if(x == 0) return 0;int left = 1;int right = x;while(left < right){long long mid = left + (right - left + 1)/2;if(mid*mid <= x) left = mid;else right = mid - 1;}return left;}
};

六、山脉数组的峰值索引

1.链接

852. 山脉数组的峰顶索引 - 力扣(LeetCode)

2.描述

3.思路

通过题意,我们可以将数据划分为这两种情况 【前半部分都是递增的数据】【后半部分全是递减的数据】,我们要找到目标值,可以认为是在前半部分的末端,也可以认为是后半部分的开端,任选一个即可

由于题目说一定是山峰数组且数组长度大于等于3,因此可以不考虑特殊情况

这题需要稍微分析的就是条件的判断:

若是认为目标值在前半段的末端,则在判断递增还是递减时,则需要前一个比较后一个

若是认为目标值在后半段开端,则判断递增还是递减时,需要后一个比较前一个

4.参考代码

class Solution {
public:int peakIndexInMountainArray(vector<int>& arr) {int left = 0;int right = arr.size()-1;while(left<right){int mid = left + (right - left + 1)/2;if(arr[mid] > arr[mid-1]) left = mid;else right = mid -1;}return left;}

七、寻找峰值

1.链接

162. 寻找峰值 - 力扣(LeetCode)

2.描述

3.思路

只需要找到数组中任意一个峰值即可,因此思路和上一题是一样的

4.参考代码

class Solution {
public:int findPeakElement(vector<int>& nums) {int left = 0;int right = nums.size()-1;while(left < right){int mid = left + (right - left + 1)/2;if(nums[mid] > nums[mid-1]) left = mid;else right = mid -1;}return left;}
};

八、搜索旋转排序数组中的最小值

1.链接

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

2.描述

3.思路

4.参考代码

class Solution {
public:int findMin(vector<int>& nums) {int left = 0;int right = nums.size()-1;int x = nums[right];while(left < right){int mid = left + (right - left)/2;if(nums[mid] > x) left = mid+1;else right = mid;}return nums[left];}
};

九、点名

1.链接

LCR 173. 点名 - 力扣(LeetCode)

2.描述

3.思路

根据题意,我们知道,若是没有人缺席,下标和数字应该会严格的一一对应的,我们可以将数据划分为前后两段【下标和元素严格对应】【下标和元素没有对应】,我们的目标值就落在后半段的开端

还需要考虑一下边界条件,若是恰好最后一位同学缺席,此时该算法会算到倒数第二位学号的同学,此时在返回时做一个判断即可

return left == records[left] ? left+1:left ;

4.参考代码

class Solution {
public:int takeAttendance(vector<int>& records) {int left = 0;int right = records.size()-1;while(left < right){int mid = left + (right - left)/2;if(records[mid] == mid) left = mid+1;else right = mid;}return left == records[left] ? left+1:left;}
};

总结

本章介绍了二分查找的算法思想,并且整理了相关的经典题目,从简单到难的去逐步递进,并且提供了链接和描述,可以直接通过链接去练习,或者直接看本篇博客去尝试思考解题,还提供了参考的思路,部分困难的题目会结合图像去分析,还有测试通过的参考代码

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Twitter Api查询用户粉丝列表

如果大家为了获取实现方式代码的话可能要让大家失望了&#xff0c;这边文章主要是为了节省大家开发时间&#xff0c;少点坑。https://api.twitter.com/2/users/:id/followers &#xff0c;这个接口很熟悉吧&#xff0c;他是推特提供的获取用户关注者&#xff08;粉丝&#xff0…

STM32-04基于HAL库(CubeMX+MDK+Proteus)中断案例(按键中断扫描)

文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式&#xff0c;生成代码四、MDK打开生成项目&#xff0c;编写HAL库的按键检测代码五、运行仿真程序&#xff0c;调试代码 一、功能需求分析 在完成GPIO输入输出案例之后&#xff0c;开始新的功能…

Node.js环境调用百度智能云(百度云)api鉴权认证三步走

方式一 :Postman脚本的方式生成v1版本的认证字符串 Postman脚本下载 下载Postman pre-request Script 设置 Authorization 示例脚本 方式二&#xff1a;在线签名工具生成 (试用于验证编程字符串签名是否有错误) 签名计算工具 https://cloud.baidu.com/signature/index.html …

使用libibverbs构建RDMA应用

本文是对论文Dissecting a Small InfiniBand Application Using the Verbs API所做的中英文对照翻译 Dissecting a Small InfiniBand Application Using the Verbs API Gregory Kerr∗ College of Computer and Information ScienceNortheastern UniversityBoston, MAkerrgccs…

HbnnMall电子商城系统介绍(功能与技术栈)

今天在看我个人网站上的文章时&#xff0c;看到了曾经在2020年自己开发的电商系统。那时我已经入职小米有一段时间了&#xff0c;基本已经对各个业务线&#xff0c;各种业务知识有了系统性的了解和学习&#xff0c;所以想自己动手写一个电商系统&#xff0c;以便进一步提高自己…

ElasticSearch7.8的下载与安装和Kibana 7.8.0工具使用安装

1、ElasticSearch7.8.0下载 elasticsearch: 官方下载地址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch 链接: https://pan.baidu.com/s/1wAKQoB3nhLhcnBlPfVOLxQ 提取码: t83n kibana: 链接: https://pan.baidu.com/s/156aD9zDdvUv8LFgDEIPoSw 提取码:…

云存储中常用的相同子策略的高效、安全的基于属性的访问控制的论文阅读

参考文献为2022年发表的Efficient and Secure Attribute-Based Access Control With Identical Sub-Policies Frequently Used in Cloud Storage 动机 ABE是实现在云存储中一种很好的访问控制手段&#xff0c;但是其本身的计算开销导致在实际场景中应用收到限制。本论文研究了…

(2024)Ubuntu源码安装多个版本的opencv并切换使用

本人工作会用到x86_64的opencv和aarch64的opencv&#xff0c;所以写下来备忘自用 一、源码编译安装 依赖库安装&#xff1a; sudo apt-get install build-essential libgtk2.0-dev libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev o…

上位机图像处理和嵌入式模块部署(qmacvisual图像清晰度)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 做过isp的同学都知道&#xff0c;图像处理里面有一个3A&#xff0c;即自动曝光、自动白平衡和自动对焦。其中自动对焦这个&#xff0c;就需要用输入…

HarmonyOS NEXT应用开发之PersistentStorage:持久化存储UI状态

前两个小节介绍的LocalStorage和AppStorage都是运行时的内存&#xff0c;但是在应用退出再次启动后&#xff0c;依然能保存选定的结果&#xff0c;是应用开发中十分常见的现象&#xff0c;这就需要用到PersistentStorage。 PersistentStorage是应用程序中的可选单例对象。此对…

Vue的学习之旅-part1

Vue的学习之旅-part1 vue介绍vue读音编程范式ES6中不用var声明变量vue的声明、初始化传参使用data中数据时要用this指向 vue中的语法糖MVVM在Vue中&#xff0c; MVVM的各层的对应位置 方法、函数的不同之处 vue介绍 vue读音 Vue 读作 /vju:/ 不要读成v u e Vuex 的x读作叉 不…

Redis高可用技术

一.Redis高可用介绍&#xff1a; 高可用是指&#xff1a;服务器正常访问的时间 衡量的标准是&#xff1a;在多长时间内可以提供正常服务99.9%、99.99%、99.999%等等 但是在Redis语境中&#xff0c; 高可用的含义似乎要宽泛一些&#xff0c;除了保证提供正常服务(如主从分离、…

IntelliJ IDEA中文---强化智能编码与重构,提升开发效率

IntelliJ IDEA 2023是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Java开发人员设计。它支持智能代码编辑、自动补全和重构&#xff0c;帮助开发者提高编码效率。同时&#xff0c;内置了丰富的调试工具&#xff0c;支持断点调试和变量监视&#xff…

C语言--文件操作

1.标准流 • stdin - 标准输⼊流&#xff0c;在⼤多数的环境中从键盘输⼊&#xff0c;scanf函数就是从标准输⼊流中读取数据。 • stdout - 标准输出流&#xff0c;⼤多数的环境中输出⾄显⽰器界⾯&#xff0c;printf函数就是将信息输出到标准输出 流中。 • stderr - 标…

丰诺畅机电科技将莅临2024年第13届生物发酵展

参展企业介绍 无锡丰诺畅机电科技有限公司&#xff0c;是一家分离设备专业制造公司&#xff0c;集开发、设计、制造、销售、服务于一体;具有专业的生产技术&#xff0c;先进的生产工艺&#xff0c;精良的制造设备&#xff0c;完善的检测手段;为满足不同用户的过滤需求&#xf…

HTTP/UDP/TCP/IP网络协议

文章目录 计算机网络基础HTTPUDPTCP连接管理(三次握手/四次挥手)TCP可靠传输(确认答应)超时重传滑动窗口流量控制拥塞控制延时应答捎带应答粘包问题其他 IP数据链路层MUT 相关问题TCP会粘包、UDP永远不会粘包 学习博客 计算机网络基础 OSI模型定义了网络互连的七层框架&#x…

esp32控制舵机---待完善

舵机有三个引脚&#xff0c;分别是电源、电源GND和信号线。如下图所示&#xff1a; ESP32-WROOM-32E的引脚的定义如下&#xff1a; 图来自乐鑫官网:ESP32-DevKitC V4 入门指南 - ESP32 - — ESP-IDF 编程指南 v5.2.1 文档 硬件连接图&#xff1a; 待补充

013——超声波模块驱动开发(基于I.MX6uLL与SR04)

目录 一、 模块介绍 1.1 产品特色 1.2 产品实物图 1.3 接口定义 1.4 测距调节 1.5 模块工作原理 1.6 注意 二、 编码思路 三、 驱动程序 四、 应用程序 五、 Makefile 六、 其它及实验 一、 模块介绍 超声波测距模块是利用超声波来测距。模块先发送超声波&#xf…

边缘计算盒子与云计算:谁更适合您的业务需求?

边缘计算盒子和云计算&#xff0c;这两个概念听起来可能有点复杂&#xff0c;但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢&#xff1f;咱们来详细说说。 边缘计算盒子&#xff0c;就像是个小型的数据处理中心&#xff0c;放在离你业务现场比较近的地方。它…

WPS二次开发专题:如何获取应用签名SHA256值

作者持续关注WPS二次开发专题系列&#xff0c;持续为大家带来更多有价值的WPS开发技术细节&#xff0c;如果能够帮助到您&#xff0c;请帮忙来个一键三连&#xff0c;更多问题请联系我&#xff08;QQ:250325397&#xff09; 在申请WPS SDK授权版时候需要开发者提供应用包名和签…