【刷题】 二分查找进阶

devtools/2024/9/25 16:43:22/

在这里插入图片描述

送给大家一句话:
你向神求助是因为相信神,神没有回应你是因为神相信你

ε≡٩(๑>₃<)۶ ε≡٩(๑>₃<)۶ ε≡٩(๑>₃<)۶ 一心向学


二分查找进阶

  • 1 前言
  • Leetcode 852. 山脉数组的峰顶索引
  • Leetcode 162. 寻找峰值
  • Leetcode 153. 寻找旋转排序数组中的最小值
  • Leetcode LCR 173. 点名
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见

1 前言

二分查找的算法思想是很好理解的。朴素二分很容易,但一般常使用左端点查找与右端点查找来解决问题。
模版:

        int left = 0 , right = nums.size() - 1;while(left < right){int mid = left + (right - left) / 2;//int mid = left + (right - left + 1) / 2;if(  // 判断条件 ){left = mid + 1;//left = mid }else{right = mid;// right = mid - 1}}return left;//return right ;
  1. while()循环条件是left < right !
  2. 注意对应关系。right里有 -1 那么对应的求中值就要有+1。把握这个规律,就不会弄乱了

下面来看几道例题,强化训练二分查找的算法思路!通过这些题的训练,就可以很熟悉二分查找算法的思想,以后遇到问题就多了一种解决手段!!!

Leetcode 852. 山脉数组的峰顶索引

上链接:852. 山脉数组的峰顶索引!!!

题目描述

在这里插入图片描述
首先我们要理解什么是山峰数组,根据题目的描述,山峰数组就是先升再下降的数组。我们要在其中寻找峰值的索引。这个问题看起来看还是挺简单的

算法思路

首先我们要判断该数组是否存在二段性???
当然有了!

  • 以峰值为分割,左边都是nums[n] < nums[n + 1] 右边都是nums[n] > nums[n + 1]

通过这个二段性我们可以来进行二分查找:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(因为nums[n] < nums[n + 1] ,mid对应的值一定不是峰值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(因为nums[n] > nums[n + 1] ,mid对应的值有可能是峰值)

有了思路,代码很简单就可以写出来,直接套用模版。

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

提交:过啦!!!!

Leetcode 162. 寻找峰值

家人们!!!跟上节奏:162. 寻找峰值

题目描述

在这里插入图片描述
这道题是上面求峰值索引的变形。这道题具有多个封值(换句话说数组是无序的),那么我们要在无序的数组寻找一个峰值。

算法思路

首先我们来看可不可以判断出来数组的二段性。和求峰值索引一样:

  • 以其中一个峰值为分割,左边一部分是nums[n] < nums[n + 1] 右边一部分是nums[n] > nums[n + 1]

那么根据这个二段性也就是可以写出算法逻辑了:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(因为nums[n] < nums[n + 1] ,右边一定存在一个峰值,mid对应的值一定不是峰值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(因为nums[n] > nums[n + 1] ,左边一定存在一个峰值,mid对应的值有可能是峰值)

有了思路,直接套用模版秒了!!!

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

提交 过啦!!!

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

上链接!!!153. 寻找旋转排序数组中的最小值

题目描述

在这里插入图片描述
根据题目描述啊,是很好理解的,就是将一个有序的数组进行移动,使其旋转,形成一个先增长然后断崖后再增长的数组,我们要找到其中的最小值

算法思路

这个题的暴力算法很简单(我们不考虑),首先也是来分析二段性。这个二段性如何进行分析呢???

  • 以其中 数组末位值为分割,由于旋转的特性,左边一部分是大于末位值 右边一部分是小于等于末位值

然后根据二段性进行算法分析:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(左边一定不存在最小值,mid 对应的值一定不是最小值)
  2. 如果中值落在右边,那么right 应该 移动到 mid(右边一定不存在一个峰值,mid对应的值有可能是最小值)

根据算法逻辑,直接秒杀:

class Solution {
public:int findMin(vector<int>& nums) {//分析二段性质//左边都大于 末位数字 右边都 小于等于 末尾数字int left = 0;int right = nums.size() - 1;while(left < right){int mid = left +(right - left) / 2;//说明mid 在最小值 左边 if(nums[mid] > nums[nums.size() - 1]){left = mid + 1;}else{right = mid;}}return nums[left];}
};

提交:过啦!!!

Leetcode LCR 173. 点名

最后一道:LCR 173. 点名!!!

题目描述

在这里插入图片描述
题目非常简单奥,就是寻找断点。(有坑哦)

算法思路

暴力算法有很多种:遍历,位运算,数学公式。我们来用更快速的二分查找算法
首先来分析二段性,这个其实不太好想

  • 以其中断点为分割,左边一部分是数组值与下标相等 ,右边一部分是数组值与下标不相等

根据这个二段性我们就可以来进行算法分析:

  1. 如果中值落在左边,那么left 应该 移动到 mid + 1(左边一定不存在断点,mid 对应的值一定不是断点)
  2. 如果中值落在右边,那么right 应该 移动到 mid(mid对应的值有可能是断点)
  3. 注意如果最后left到了最右边,那么缺少的是最后一名同学,要进行一个判断

根据这个算法逻辑,我们书写代码:

class Solution {
public:int takeAttendance(vector<int>& nums) {//寻找二段性//左边下标对应 右边下标不对应int left = 0 ; int right = nums.size() - 1;while(left < right){int mid = left + (right - left ) / 2;//if(nums[mid] == mid){left = mid + 1;}else{right = mid;}}//left到了最右边,缺少的是最后一名同学,要进行一个判断return nums[left] == left ? nums.size() : left ;}
};

提交过啦!!!

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见


http://www.ppmy.cn/devtools/5661.html

相关文章

蓝桥杯刷题-数星星

1265. 数星星 - AcWing题库 /* 题目中的y是递增&#xff0c;不影响 */ /* 直接看作一维数组的更新维护 */ /* 将数据二进制化&#xff0c;拿最低位的1 */ /* 转化为线段树的解法才是核心 */ /* 思想是前缀和 */ #include <bits/stdc.h>using namespace std;const int N …

OpenCV下载安装教程(Windows)

一、什么是OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个广泛使用的开源计算机视觉库&#xff0c;旨在提供丰富的图像和视频处理功能。它最初由Intel于1999年开发&#xff0c;并演变成为一个全球性的开源项目&#xff0c;得到了众多开发者…

途游游戏,科锐国际(计算机类),快手,得物,蓝禾,奇安信,顺丰,康冠科技,金证科技24春招内推

途游游戏&#xff0c;科锐国际&#xff08;计算机类&#xff09;&#xff0c;快手&#xff0c;得物&#xff0c;蓝禾&#xff0c;奇安信&#xff0c;顺丰&#xff0c;康冠科技&#xff0c;金证科技24春招内推 ①得物 【岗位】技术&#xff0c;设计&#xff0c;供应链&#xff0…

【银角大王——Django课程——ORM】

Django课程——ORM框架 Django 模型使用自带的 ORMORM 解析过程:ORM 对应关系表&#xff1a;下载mysqlclient安装包创建数据库——ORM只能操作表&#xff0c;无法创建数据库。连接数据库——修改settings中的DATABASESDjango操作表&#xff0c;在models.py文件中编写——操作表…

Java 多线程加法求和

Java 多线程加法求和 代码 先上代码再上解析&#xff1a; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger;public class Sum implements …

施耐德 PLC 及模块 ModbusTCP 通信配置方法

1. 通过【I/O扫描器】服务进行读写 相关文档&#xff1a;各模块说明书仅 NOE 网卡模块、部分 CPU 自带的网口支持 优点&#xff1a;不需要额外编程&#xff0c;系统自动周期型读写数据缺点&#xff1a;扫描周期不定&#xff0c;程序无法控制数据刷新的时序 2. 通过内部程序…

卷王问卷考试系统/SurveyKing调查系统源码

SurveyKing是一个功能强大的开源调查问卷和考试系统&#xff0c;它能够快速部署并适用于各个行业。 这个系统提供了在线表单设计、数据收集、统计和分析等功能&#xff0c;支持20多种题型&#xff0c;提供多种创建问卷的方式和设置。 项 目 地 址 &#xff1a; runruncode.c…

springboot 启动非web应用

问题描述 非web应用&#xff0c;启动完成自动退出 问题原因 因为任务完成了&#xff0c;所以系统退出了。需要给spring一个任务&#xff0c;而且这个任务无法解决 包括&#xff1a; web定时任务一个无法完成的任务 解决方案 其中一个是&#xff1a; 非web不自动退出 注意…