coding ability 展开第五幕(二分查找算法)超详细!!!!

.在这里插入图片描述

.

文章目录

  • 前言
  • 二分查找
  • 搜索插入的位置
    • 思路
  • x的平方根
    • 思路
  • 山脉数组的峰顶索引
    • 思路
  • 寻找旋转排序数组中的最小值
    • 思路
  • 总结

前言

本专栏上篇博客已经把滑动指针收尾啦
现在还是想到核心——一段连续的区间,有时候加上哈希表用起来很爽
今天我们来学习新的算法知识——二分查找,相信大家都不陌生
二分查找,怎么说呢,清晰了解之后,其实代码就几行
话不多说,跟我一起来瞅瞅吧

二分查找

首先我们来学习两道经典例题,有了例题和板子,才能更好的扩展和延伸,应对不同的场景
二分查找
在这里插入图片描述
其实乍一看,直接遍历一遍不就好了吗,但是今天我们的主题是二分查找
所以这一题来学习一下二分的第一个最简单的板子
解法一就是暴力循环找目标值
解法二:
在这里插入图片描述
其实核心就是二段性,只要给的数据有二段性,我们就能用二分
最朴素的就是不断的找 mid 然后判断 ,再进到新的区间 ,不断二分
看看这题代码,其实大家应该都会写的,最基础的二分板子

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

可能觉得二分就这么简单吗?? 不不不,还有另外两个板子,会有点麻烦
在排序数组中查找元素的第一个和最后一个位置
在这里插入图片描述
这题能把另外两个二分的板子完美诠释出来,在做这一题之前,我们先来了解两种情况
前面我们的朴素版本就是 大于 等于 小于 三种情况。
现在我们来想想 左边区间是小于目标值 右边区间是大于等于目标值 两种情况怎么处理
也就是找区间的左端点,如下图:
在这里插入图片描述
相比于前面的朴素板子,有很多细节差别
—left 和 right 的更新, 当 x 小于目标值时,那就是左边区间,这时候left——mid的区间都是不满足条件的,因为左边区间都是小于目标值,所以 left 要更新为 mid+1当 x 大于等于目标值时,因为我们右边区间默认是大于等于目标值的区间,我们的 right 如果更新为 mid - 1,有可能当前的mid就是要找寻的点所以 right 应该更新为 mid
—循环条件 当 left == right 时,就是我们要找的答案,这个时候如果循环条件为 left<=right ,会进入死循环
mid的取值,看下图,假设就剩下两个值,目标值是left先用第一种方法 mid 就是 left,这个时候 x >= 目标值所以right == mid刚好left 和 right 相等,找到目标值,如果取用第二种方法取mid为right,这个时候 x >= 目标值,right 和 mid 相等,然后left还是小于right,死循环,所以当我们把区间分成左边完全小于目标值,右边大于等于目标值的时候,就用第一种
在这里插入图片描述
左端点结束了,接下来就是右端点了
也就是左边区间小于等于目标值,右边区间完全大于目标值
在这里插入图片描述
需要注意的细节还是
—left 和 right 的更新 ,当 x > 目标值的时候 right更新为 mid - 1,因为右边区间都是大于目标值的, 当 x <= 目标值的时候left更新为mid,因为左边区间小于等于目标值,可能mid的位置就是目标值
—left < right left 不能等于 right
—还是 mid 的取值问题,再来回到这个图在这里插入图片描述
我们先使用第一种,当right为目标值时,更新 mid 是刚好为 left,这个时候left更新为mid,right还是大于left,陷入死循环,使用第二种的话,更新mid为rightleft更新为mid也就是right,left和right相等,跳出循环,找到目标值。所以当区间分成左区间小于等于,右区间大于时,用第二种取mid

好了,找左右端点我们都学会了这题,也是能稳稳拿下了
题目要求找到目标值的左右端点,那我们来一次找左端点的操作,再来一次右端点的操作就好啦,话不多说,上代码

class Solution 
{
public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.size() == 0)return{-1, -1};int begin = 0;int left = 0, right = nums.size() - 1;while(left < right)   //  找左端点{int mid = left + (right - left) / 2;if(nums[mid] < target)left = mid + 1;elseright = mid;}if(nums[left] != target) return {-1, -1};begin = left;right = nums.size() - 1;while(left < right)  //  找右端点{int mid = left + (right - left + 1) / 2;if(nums[mid] > target)right = mid - 1;elseleft = mid;}return {begin, right};}
};

搜索插入的位置

在这里插入图片描述

思路

这题看来就是左区间小于,又区间大于等于,二段性就分好啦
假设插入的坐标是x,那么x左边都是小于目标值的,右区间都是大于等于目标值的
我们可以用查询左端点的板子,直接返回找到的左端点
还有一种特殊情况就是,数据插入在末尾,原本的数据全部小于目标值的,就把这一点处理一下就好了
话不多说,上代码

class Solution 
{
public:int searchInsert(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] < target)  //  特殊情况,所有数据都比目标值小left = mid + 1;		//	返回right + 1elseright = mid;}if(nums[left] < target)return left + 1;elsereturn right;} 
};

x的平方根

在这里插入图片描述

思路

本题第一种思路就是暴力枚举就好了,0-x/2区间一个一个枚举,挺简单的思路,就不多赘述了
第二种思路就是二分,我们可以用右端点的板子,设定 i * i <= x为条件,进行二分,最终返回的就是小于等于算数平方根的下标, 话不多说,上代码

class Solution 
{
public:int mySqrt(int x) {if(x == 0)return 0;long long right = x / 2, left = 1;while(left < right){long long  mid = left + (right - left + 1) / 2; // 查询右端点取中点处理if(mid * mid > (long long)x)right = mid - 1;elseleft = mid;}return left;        }
};

其实核心就是找到数据的二段性,然后看情况选择二分查找左端点还是右端点就好啦

山脉数组的峰顶索引

在这里插入图片描述

思路

题目的意思是找到山脉的顶峰,第一种思路当然就是暴力查找了,找到最大值就行
第二种思路就是我们可以把山脉分成两份,二段性不就来了嘛,一段单调增,一段单调减
然后根据情况查找左端点或者右端点就好啦
我们把左区间设定为递增到山顶的区间,右区间就是下山的区间
这个时候应该用我们的查询右端点的板子,然后我们的判断条件可以设为 arr[mid] > arr[mid - 1]
话不多说,看代码

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

当然,也可以用查询左端点的板子来写

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

其实,核心就是找到二段性,然后再找判断条件

寻找旋转排序数组中的最小值

在这里插入图片描述

思路

题目的二段性意思已经写在脸上了,如图
在这里插入图片描述
我们直接设定右端点为 x ,然后上查找左端点的板子,这个x用来判断区间条件
就是两步,二段性,区间条件,话不多说,上代码

class Solution 
{
public:int findMin(vector<int>& nums) {int left = 0, right = nums.size() - 1;int x = nums[right];while(left < right){int mid = left + (right - left) / 2;if(nums[mid] > x) //  当前值大于  x  表示在左区间left = mid + 1;   //  更新leftelseright = mid;}return nums[left];}
};

总结

二分查找是一种高效的搜索算法,核心在于利用数据的二段性将区间不断二分,快速定位目标。本文通过经典例题解析了三种常见场景的二分应用:

  1. 基本查找:适用于有序数组,通过比较中间值与目标调整区间,时间复杂度O(logN)。
  2. 边界查找
    • 左边界:右区间≥目标,循环条件left<right,mid取左中点,更新策略确保不遗漏可能解。
    • 右边界:左区间≤目标,mid取右中点,避免死循环。
  3. 特殊场景:如山脉数组峰值、旋转数组最小值,通过分析数据规律(如单调性变化点)构造二段性条件。

关键点

  • 循环条件选择(left<rightleft<=right)。
  • mid计算方式(防止溢出)与边界更新策略。
  • 处理目标不存在或越界的特殊情况。

掌握二分查找的核心在于理解区间划分逻辑,灵活选择模板,结合问题特点设计判断条件,从而高效解决复杂查找问题

今天的内容就到这里啦,不要走开小编持续更新中~~~

在这里插入图片描述

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

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

相关文章

文献阅读篇#2:YOLO改进类的文章如何高效进行文献阅读(对于初学者)

对于初学者来说&#xff0c;文献阅读是非常非常重要的一个学习方式&#xff0c;好的文献阅读方法会让学习的效率翻倍。我希望能够总结出一套比较有效的文献阅读方法&#xff0c;并通过记录的方法来找到不足和可改进之处 一、文献检索 对于初学者来说&#xff0c;应当先从中文…

数智读书笔记系列021《大数据医疗》:探索医疗行业的智能变革

一、书籍介绍 《大数据医疗》由徐曼、沈江、余海燕合著&#xff0c;由机械工业出版社出版 。徐曼是南开大学商学院副教授&#xff0c;在大数据驱动的智能决策研究领域颇有建树&#xff0c;尤其在大数据驱动的医疗与健康决策方面有着深入研究&#xff0c;曾获天津优秀博士论文、…

MarsCode AI实战:利用DeepSeek 快速搭建你的口语学习搭子

资料来源&#xff1a;火山引擎-开发者社区 成品抢先看&#xff01; 自从MarsCode AI Chat模型全新升级&#xff0c;接入 Deepseek-R1、Deepseek-V3和豆包大模型1.5 三大模型&#xff0c;越来越多朋友注意到了AI编程能给我们带来的无限可能&#xff0c;也开始跃跃欲试想要尝试从…

Linux环境变量:深入解析与实用指南

目录 一、环境变量概述 二、环境变量的作用 三、环境变量的类型 3.1系统环境变量 3.2用户环境变量 四、环境变量的操作 4.1查看环境变量 4.2设置环境变量 4.3删除环境变量 五、环境变量的配置文件 六、环境变量的最佳实践 七、总结 环境变量是Linux系统中至关重要的…

C++20 线程协调类:从入门到精通

文章目录 1. 初识线程协调2. std::barrier&#xff1a;多线程同步的屏障2.1 核心函数2.2 示例代码2.3 高级用法2.4 适用场景 3. std::latch&#xff1a;一次性同步原语3.1 核心函数3.2 示例代码3.3 高级用法3.4 适用场景 4. std::counting_semaphore&#xff1a;可重用的同步原…

【Linux网络】手动部署并测试内网穿透

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

MySQL中的锁机制:从全局锁到行级锁

目录 1. 锁的基本概念 2. 全局锁 2.1 全局锁的定义 2.2 全局锁的类型 2.3 全局锁的使用场景 2.4 全局锁的实现方式 2.5 全局锁的优缺点 2.6 全局锁的优化 3. 表级锁 3.1 表级锁的类型 3.2 表级锁的使用场景 3.3 表级锁的优缺点 4. 意向锁&#xff08;Intention Lo…

2025年渗透测试面试题总结- 某亭-安全研究员(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、SQL注入过滤单引号绕过方法 二、MySQL报错注入常用函数 三、报错注入绕WAF 四、MySQL写文件函数…

MacOS安装 nextcloud 的 Virtual File System

需求 在Mac上安装next cloud实现类似 OneDrive 那样&#xff0c;文件直接保存在服务器&#xff0c;需要再下载到本地。 方法 在 官网下载Download for desktop&#xff0c;注意要下对版本&#xff0c;千万别下 Mac OS默认的那个。 安装了登录在配置过程中千万不要设置任何同…

1.8 函数的连续性和间断点

1.连续的定义 2.间断点的定义 3.间断点的分类

Unity 云渲染本地部署方案

Unity Render Streaming 云渲染环境搭建 0.安装 Unity Render Streaming 实现原理: 服务器与客户端实现功能包括: 详细内容见官方文档&#xff1a; 官方文档: https://docs.unity3d.com/Packages/com.unity.renderstreaming3.1/manual/tutorial.html Unity 流送云渲染介绍: …

每日一题力扣3248.矩阵中的蛇c++

3248. 矩阵中的蛇 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int finalPositionOfSnake(int n, vector<string>& commands) {int i 0;int j 0;for (int k0;k<commands.size();k) {if (commands[k] "RIGHT")j;else if (comma…

本地基于Ollama部署的DeepSeek详细接口文档说明

前文&#xff0c;我们已经在本地基于Ollama部署好了DeepSeek大模型&#xff0c;并且已经告知过如何查看本地的API。为了避免网络安全问题&#xff0c;我们希望已经在本地调优的模型&#xff0c;能够嵌入到在本地的其他应用程序中&#xff0c;发挥本地DeepSeek的作用。因此需要知…

FPGA 以太网通信(三)

一、UDP协议 UDP&#xff08;User Datagram Protocol Protocol&#xff09;&#xff0c;即用户数据报协议&#xff0c;是一种面向无连接的传输层协议。UDP和TCP协议都属于传输层协议&#xff0c;在网络传输中同一 IP 服务器需要提供各种不同的服务&#xff0c;为了区别不同的服…

期刊分区表2025年名单下载(经济学、管理学)

2025年期刊分区表包括SCIE、SSCI、A&HCI、ESCI和OAJ&#xff0c;共设置了包括自然科学、社会科学和人文科学在内的21个大类 本次分享的是期刊分区表2025年名单经济学类、管理学类&#xff0c;一共7631025条 一、数据介绍 数据名称&#xff1a;期刊分区表2025年名单 数据…

如何在MCU工程中启用HardFault硬错误中断

文章目录 一、HardFault出现场景二、启动HardFault三、C代码示例 一、HardFault出现场景 HardFault&#xff08;硬故障&#xff09; 错误中断是 ARM Cortex-M 系列微控制器中一个较为严重的错误中断&#xff0c;一旦触发&#xff0c;表明系统遇到了无法由其他异常处理机制解决…

智能体开发革命:灵燕平台如何重塑企业AI应用生态

在AI技术深度渗透产业的今天&#xff0c;**灵燕智能体平台**以“全生命周期管理”为核心&#xff0c;为企业提供从智能体开发、协作到落地的闭环解决方案&#xff0c;开创了AI应用工业化生产的新模式。 三位一体的智能体开发体系 1. Agent Builder&#xff1a;零门槛构建专属…

机器学习之支持向量机(SVM)算法详解

文章目录 引言一、 什么是支持向量机&#xff08;SVM&#xff09;二、 SVM的基本原理三、数学推导1.线性可分情况2. 非线性可分情况3. 核函数 四、SVM的优缺点优点&#xff1a;缺点&#xff1a; 五、 应用场景六、 Python实现示例七、 总结 引言 支持向量机&#xff08;Suppor…

【C++进阶】深入探索类型转换

目录 一、C语言中的类型转换 1.1 隐式类型转换 1.2. 显式类型转换 1.3.C语言类型转换的局限性 二、C 类型转换四剑客 2.1 static_cast&#xff1a;静态类型转换&#xff08;编译期检查&#xff09; 2.2 dynamic_cast&#xff1a;动态类型转换&#xff08;运行时检查&…

机器学习之KL散度推导

机器学习之KL散度推导 预备知识 熵、交叉熵、条件熵 熵 (Entropy) 这一词最初来源于热力学。1948年&#xff0c;克劳德爱尔伍德香农将热力学中的熵引入信息论&#xff0c;所以也被称为香农熵 (Shannon entropy)、信息熵 (information entropy)。 对于具体熵的定义和用法推荐…