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.mzph.cn/news/790480.shtml

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

相关文章

XSS 与 CSRF 攻击——有什么区别,如何加以防护

跨站脚本(XSS)和跨站请求伪造(CSRF)&#xff0c;它们将恶意脚本注入目标系统&#xff0c;以进一步利用技术栈或窃取用户数据。 什么是 XSS 和 CSRF? CSRF和XSS都是客户端攻击&#xff0c;它们滥用同源策略&#xff0c;利用web应用程序和受害用户之间的信任关系。XSS和跨站脚…

WPS二次开发系列:以自动播放模式打开PPT文档

在前面文章中 WPS SDK打开文档并实现保存回传 介绍了如何使用WPS SDK打开文档&#xff0c;那么我们是否能够实现在打开WPS 文档的时候能够传递一些参数来控制打开文档的行为呢&#xff0c;经过研究WPS SDK相关文档和API&#xff0c;最终实现了 以自动播放方式打开PPT文档功能。…

Spring Cloud微服务入门(二)

微服务的技术栈 服务治理&#xff1a; 服务注册、发现、调用。 负载均衡&#xff1a; 高可用、集群部署。 容错&#xff1a; 避免雪崩、削峰、服务降级。 消息总线&#xff1a; 消息队列、异步通信&#xff0c;数据一致性。 网关&#xff1a; 校验路径、请求转发、服务集成…

【Web】2024红明谷CTF初赛个人wp(2/4)

目录 ezphp playground 时间原因只打了2个小时&#xff0c;出了2道&#xff0c;简单记录一下 ezphp 参考文章 PHP filter chains: file read from error-based oracle https://github.com/synacktiv/php_filter_chains_oracle_exploit 用上面的脚本爆出部分源码&#xff…

SSM项目转Springboot项目

SSM项目转Springboot项目 由于几年前写的一个ssm项目想转成springboot项目&#xff0c;所以今天倒腾了一下。 最近有人需要毕业设计转换一下&#xff0c;所以我有时间的话可以有偿帮忙转换&#xff0c;需要的私信我或&#xff0b;v&#xff1a;Arousala_ 首先创建一个新的spr…

蓝桥杯第793题——排水系统

题目描述 对于一个城市来说&#xff0c;排水系统是极其重要的一个部分。 有一天&#xff0c;小 C 拿到了某座城市排水系统的设计图。排水系统由 n 个排水结点&#xff08;它们从 1∼n 编号&#xff09;和若干个单向排水管道构成。每一个排水结点有若干个管道用于汇集其他排水…

git分支-基本分支与合并

问题假设 让我们通过一个简单的分支和合并的例子&#xff0c;演示在实际工作中可能会使用的工作流程。将按照以下步骤进行&#xff1a; 在网站上进行一些工作。为正在开发的新用户故事创建一个分支。在该分支上进行一些工作。 在这个阶段&#xff0c;我们可能会接到一个电话…

线上研讨会 | 应对汽车毫米波雷达设计中的电磁挑战

智能汽车、新能源汽车最近几年一直是汽车行业关注的热点&#xff0c;随着5G技术越来越普及&#xff0c;汽车智能化发展将越来越迅速。从传统汽车到智能汽车&#xff0c;不是简单功能的增强&#xff0c;而是从单一功能的交通工具变成可移动的办公和娱乐空间&#xff0c;成为物联…

STM32实现软件SPI对W25Q64内存芯片实现读写操作

先看看本次实验的成果吧&#xff1a; 这么简单的一个程序&#xff0c;我学习了一个星期左右&#xff0c;终于把所有的关节都打通了。所有代码都能什么都不看背着敲出来了。为了使自己的记忆更为清晰&#xff0c;特意总结了一个思维导图&#xff0c;感觉自己即便是日后忘记了看一…

机器学习的15个概念

机器学习 有监督学习 有监督学习是利用训练数据集进行预测的机器学习任务。有监督学习可以分为分类和回归。回归用于预测“价格”“温度”或“距离”等连续值&#xff0c;而分类用于预测“是”或“否”、“垃圾邮件”或“非垃圾邮件”、“恶性”或“良性”等类别。 分类包含…

如何保护IP地址?安全匿名上网的方法

当互联网成为每个家庭的重要组成部分后&#xff0c;IP地址就成了你的虚拟地址。您的请求从该地址开始&#xff0c;然后 Internet 将消息发送回该地址。那么&#xff0c;您担心您的地址被泄露吗&#xff1f; 对于安全意识高或者某些业务需求的用户&#xff0c;如果您正在寻找保护…

C++ 静态库与动态库的生成和使用:基于 VS Studio 生成 newmat 矩阵库的静态库与动态库

文章目录 Part.I IntroductionChap.I 预备知识Chap.II 静态库与动态库区分 Part.II 静态库的生成与使用 (newmat)Chap.I 生成静态库Chap.II 使用静态库 Part.III 动态库的生成与使用 (newmat)Chap.I 生成动态库Chap.II 使用动态库 Part.IV 文件内容Chap.I test.cpp (静态库)Cha…

Hadoop Yarn

首先先从Yarn开始讲起&#xff0c;Yarn是Hadoop架构的资源管理器&#xff0c;可以管理mapreduce程序的资源分配和任务调度。 Yarn主要有ResourceManager、NodeManage、ApplicationMaster&#xff0c;Container ResourceMange负责管理全局的资源 NodeManage&#xff08;NM&a…

九河云:在AWS上实现跨region VPC互联

如何跨region实现不同VPC之间的对等链接&#xff1f;九河云为您介绍AWS跨region连接方案。 说明&#xff1a;VPC-A位于弗吉尼亚region&#xff0c;VPC-B位于俄勒冈region 本文将在同一账户的弗吉尼亚和俄勒冈VPC中各启用一台EC2&#xff08;本文已提前创建好VPC、EC2等资源&am…

Spring Boot中前端通过请求接口下载后端存放的Excel模板

导出工具类 package com.yutu.garden.utils;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger;…

云计算的安全需求

目录 一、概述 二、云安全服务基本能力要求 三、信息安全服务&#xff08;云计算安全类&#xff09;资质要求 3.1 概述 3.2 资质要求内容 3.2.1 组织与管理要求 3.2.2 技术能力要求 四、云安全主要合规要求 4.1 安全管理机构部门的建立 4.2 安全管理规范计划的编制 4…

C++ //练习 11.3 编写你自己的单词计数程序。

C Primer&#xff08;第5版&#xff09; 练习 11.3 练习 11.3 编写你自己的单词计数程序。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*************************************************************************> …

2024最新AI创作系统ChatGPT源码+Ai绘画网站源码,GPTs应用、AI换脸、插件系统、GPT文档分析、GPT语音对话一站式解决方案

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

记 log4j-over-slf4j.jar AND bound slf4j-log4j12.jar jar包冲突问题

报错信息如下 SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError. SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details. Exception in thread “main” java.lan…

NineData云原生智能数据管理平台新功能发布|2024年3月版

数据库 DevOps - 大功能升级 SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;在产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能…