【二分查找】Leetcode例题
【1】69. x 的平方根 - 力扣(LeetCode)
🍡解题思路:首先想到的是暴力查找,从1开始依次比较x与num*num的大小,然后找出满足num*num<=x且(num+1)*(num+1)>x的num值;再来看看能不能优化一下,因为是有序的比较,因此可以考虑使用二分查找算法来解决此题。
🍡算法原理:首先找出二段性,观察发现,所求出算数平方根只保留整数部分,因此可以将结果值划分到左段,将num*num<=x的划分为一段,num*num>x的划分为另一段,根据我之前发过的二分查找算法模板介绍的博客(【二分查找】模板+例题),可以发现这就是典型的查找右端点的二分查找算法,找出条件判断语句的判断条件即可求解
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,由于是右端点二分查找算法,因此是mid=left+(right-left+1)/2(不清楚为什么的可以看看【二分查找】模板+例题)
4)编写条件判断语句:
1.若mid*mid<=x,left=mid
2.若mid*mid>x,right=mid-1
细节处理:由于题目是从0开始的,因此小于1的
注意:由于题目给出的数字范围太大,可能会出现溢出情况,因此mid用longlong类型,left和right也可以设置成longlong类型;
🍡实现代码:
int mySqrt(int x) {if(x<1)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 if(mid*mid>x){right=mid-1;}}return left;}
【2】35. 搜索插入位置 - 力扣(LeetCode)
🍡解题思路:首先想到暴力查找,依次比较nums[i]与target的大小,如果nums[i]>=target那么就输出对应位置下标,但是题目要求时间复杂度为O(logN),因此考虑使用二分查找算法解决
🍡算法原理:可以发现数组的二段性,将数组划分为x<target和x>=target两部分,要求解包含在x>=target部分,很明显是寻找左端点的二分查找
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,由于是左端点二分查找算法,因此是mid=left+(right-left)/2
4)编写条件判断语句:
1.若nums[mid]<target,left=mid+1
2.若nums[mid]>=target,right=mid
细节处理:如果target的值比nums中所有元素都要大,插入位置就是nums.size(),即nums的下一个位置的下标;如果不单独写,输出的就是nums最后一个位置下标,是错误的。
🍡实现代码:
int searchInsert(vector<int>& nums, int target) {int sz=nums.size();if(target<nums[0]){return 0;}else if(target>nums[sz-1]){return sz;}int left=0;int right=sz-1;int mid=0;while(left<right){mid=left+(right-left)/2;if(nums[mid]>=target){right=mid;}else if(nums[mid]<target){left=mid+1;}}return right;}
【3】852. 山脉数组的峰顶索引 - 力扣(LeetCode)
🍡解题思路:题目要求的峰值元素,比左右两侧的元素都要大,因此可以通过比较相邻元素的大小来确定峰值元素位置
🍡算法原理:寻找二段性,会发现峰值左侧元素都是比它下一个元素小,峰值右侧(包含峰值在内)都是比它下一个元素大;这样就划分出了二段性,会发现是寻找左端点的二分查找算法。
(同理,也可以通过将当前元素与上一个元素比较,将峰值划分在左侧,通过寻找右端点的二分查找算法求解)
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,由于是左端点二分查找算法,因此是mid=left+(right-left)/2
4)编写条件判断语句:
1.若arr[mid]<arr[mid+1],left=mid+1
2.若arr[mid]>arr[mid+1],right=mid
🍡实现代码:
int peakIndexInMountainArray(vector<int>& arr) {int left=0;int right=arr.size()-1;while(left<right){int mid=left+(right-left)/2;if(arr[mid]>arr[mid+1]){right=mid;}else if(arr[mid]<arr[mid+1]){left=mid+1;}}return left;}
【4】162. 寻找峰值 - 力扣(LeetCode)
🍡解题思路:可以分为三种情况:
1、完全上升趋势
2、完全下降趋势
3、波折曲线
三种情况能找到峰值,因为nums的左侧趋向于-∞,右侧趋向于+∞;如果是情况1,那么最右侧元素就是峰值;如果是情况2,那么最左侧元素就是峰值;如果是情况3可以找到其中一个峰值。观察发现,若nums[i]>nums[i+1],那么该值右侧呈现下降趋势,而nums最左侧趋向于-∞,因此该值左侧一定存在一个峰值;而当nums[i]<nums[i+1],同理该值右侧一定存在一个峰值
🍡算法原理:通过上述分析,可以得到二段性,当nums[i]>nums[i+1](包含峰值元素在内)时,向左搜索;当nums[i]<nums[i+1]时,向右搜索。因此可以使用左端点的二分查找算法
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,由于是左端点二分查找算法,因此是mid=left+(right-left)/2
4)编写条件判断语句:
1.若nums[mid]<nums[mid+1],left=mid+1
2.若nums[mid]>=nums[mid+1],right=mid
🍡实现代码:
int findPeakElement(vector<int>& nums) {int left=0;int right=nums.size()-1;while(left<right){int mid=left+(right-left)/2;if(nums[mid]>nums[mid+1])//找出二段性{right=mid;}else if(nums[mid]<nums[mid+1]){left=mid+1;}}return left;}
【5】153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)
🍡解题思路:旋转之后变为两段升序数组,通过观察找到二段性,利用二分查找求解
🍡算法原理:可以发现旋转之后AB段的元素都比最后一个元素D的值大,而CD段元素(包含最小值在内)都比元素D的值小;因此划分出二段性。可以发现可利用左端点的二分查找求解
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,由于是左端点二分查找算法,因此是mid=left+(right-left)/2
4)编写条件判断语句:
1.若nums[mid]>nums[sz],left=mid+1
2.若nums[mid]<=nums[sz],right=mid
🍡实现代码:
int findMin(vector<int>& nums) {int left=0;int right=nums.size()-1;int sz=nums.size();while(left<right){int mid=left+(right-left)/2;if(nums[mid]>nums[sz-1]){left=mid+1;}else{right=mid;}}return nums[right];}
【6】LCR 173. 点名 - 力扣(LeetCode)
🍡解题思路:可以求解的方式有很多,可以通过累加和的方式求解,也可以通过元素与下标待遇比的方式求解。同样也能用二分查找的方式求解
🍡算法原理:寻找二段性,可以发现缺失值左侧元素的下标值都和元素值相等,而右侧元素的下标值都和元素值不相等,因此根据这个特性划分出二段性
🍡解题步骤:
1)定义左右边界left,right
2)定义循环判断条件left<right
3)设置mid值,如果是右端点二分查找算法,因此是mid=left+(right-left)/2
4)编写条件判断语句:
1.若records[mid]==mid,left=mid+1
2.若records[mid]!=mid,right=mid
细节:右端点二分查找和左端点二分查找都行,要不就是插入元素左侧要不就是插入元素右侧,只需要最后返回的时候判断一下即可。可能存在records=[1,2,3]这种情况,定位在第一个元素;存在records=[0,1,2,3]这种情况,定位在最后一个元素的下一个;如果这两种情况单独考虑,那么使用右端点二分,就可以return left+1;而使用左端点二分,就可以return left-1;
为了方便起见,可以直接判断一下while结束之后在插入元素左侧还是右侧再来确定返回值即可
🍡实现代码:
int takeAttendance(vector<int>& records) {int left=0;int right=records.size()-1;//找出二段性,缺失值左侧都是等于下标,右侧都是!=下标while(left<right){int mid=left+(right-left+1)/2;if(records[mid]!=mid)right=mid-1;elseleft=mid;}return left==records[left]?(left+1):left;//如果是缺失值左侧元素,left+1就是缺失值;如果是缺失值右侧元素,那么left就是缺失值}
int takeAttendance(vector<int>& records) {int left=0;int right=records.size()-1;if(records[0]!=0) return 0;if(records[right]==right) return right+1;//找出二段性,缺失值左侧都是等于下标,右侧都是!=下标while(left<right)//左端点的二分{int mid=left+(right-left+1)/2;if(records[mid]!=mid)right=mid-1;elseleft=mid;}//return left==records[left]?(left+1):left;return left+1;}
int takeAttendance(vector<int>& records) {int left=0;int right=records.size()-1;if(records[0]!=0) return 0;if(records[right]==right) return right+1;//找出二段性,缺失值左侧都是等于下标,右侧都是!=下标while(left<right)//右端点的二分{int mid=left+(right-left)/2;if(records[mid]!=mid)right=mid;elseleft=mid+1;}//return left==records[left]?(left+1):left;return left;}
相关文章:

【二分查找】Leetcode例题
【1】69. x 的平方根 - 力扣(LeetCode) 🍡解题思路:首先想到的是暴力查找,从1开始依次比较x与num*num的大小,然后找出满足num*num<x且(num1)*(num1)>x的num值;再来看看能不能优化一下&…...
gitlab配置调试minio
官方文档 rails console 调试 查看配置Settings.uploads.object_store加载minio clientrequire fog/awsfog_connection Fog::Storage.new(provider: AWS,aws_access_key_id: 你的MINIO_ACCESS_KEY,aws_secret_access_key: 你的MINIO_SECRET_KEY,region: <S3 region>,e…...
Vue实战技巧:如何展示附件(PDF、MP4、Excel、Zip等)并修改名称下载
大家好,今天给大家分享一篇关于在Vue项目中展示附件(PDF、MP4、Excel、Zip等)并修改名称下载的教程。在实际开发过程中,这个功能非常实用,下面我们就一起来学习一下。 一、准备工作 首先,确保你的项目中已经…...

AI证件照制作 API 对接说明
AI证件照制作 API 对接说明 本文将介绍一种 AI证件照制作 API 对接说明,它是可以通过输入人像照片URL以及自己喜欢的模板来制作各种风格的证件照。 接下来介绍下 AI证件照制作 API 的对接说明。 申请流程 要使用 API,需要先到 AI证件照制作 API?inv…...

Macos用brew安装Nodejs亲手教程
首先确保brew已安装,搜索node资源,命令如下: brew search nodejs 演示结果如下: 安装nodejs brew install node22 或 brew install node 出现如下界面 表示正在安装,安装成功后,提示如下信息࿱…...
Node.js 新手教程
1、nodejs简介 Node.js 是一个开源和跨平台的 JavaScript 运行时环境。它是几乎所有类型项目的流行工具! Node.js 在浏览器之外运行 V8 JavaScript 引擎(Google Chrome 的核心)。这使得 Node.js 的性能非常出色。 Node.js 应用程序在单个进…...

Latex转word(docx)或者说PDF转word 一个相对靠谱的方式
0. 前言 投文章过程中总会有各种各样的要求,其中提供word格式的手稿往往是令我头疼的一件事。尤其在多公式的文章中,其中公式转换是一个头疼的地方,还有很多图表,格式等等,想想就让人头疼欲裂。实践中摸索出一条相对靠…...
前端热门面试题目——React、Node
img 标签的 srcset 属性的作用 srcset 属性允许开发者为不同设备或分辨率提供多个图像选项,优化加载的图片以适应设备的屏幕大小和分辨率。这提高了性能和用户体验。 示例: <img src"default.jpg" srcset"small.jpg 480w, medium.j…...

Ansible自动化一键部署单节点集群架构
自动化部署利器:Ansible 一键部署脚本 在现代IT基础设施管理中,Ansible以其简洁、强大的自动化能力脱颖而出。以下是精心打造的Ansible自动化一键部署脚本,旨在简化部署流程,提升效率,确保一致性和可靠性。 通过这个…...

电脑插入耳机和音响,只显示一个播放设备
1. 控制面板-硬件和声音-Realtek高清音频-扬声器-设备高级设置-播放设备里选择使用前部和后部输出设备同时播放两种不同的音频流 在声音设置中就可以看到耳机播放选项...

家政小程序开发,打造便捷家政生活小程序
目前,随着社会人就老龄化和生活压力的加重,家政服务市场的需求正在不断上升,家政市场的规模也正在逐渐扩大,发展前景可观。 在市场快速发展的影响下,越来越多的企业开始进入到市场中,同时家政市场布局也发…...

tcpdump抓包wireshark分析
背景 分析特定协议的数据包,如 HTTP、DNS、TCP、UDP 等,诊断网络问题,例如连接故障、延迟和数据包丢失。 大概过程 1.安装tcpdump yum update yum install tcpdump2.抓包,从当前时间起,一小时后停止,…...

文件无法直接拖入zotero
解决方法:取消管理员权限打开zotero。 具体如下:右键zotero应用程序,打开属性,选择“兼容性”,点击底下的“更改所有用户的设置”,在弹出的框中取消“以管理员身份运行此程序”。如下所示:...
使用 useMemo 和 React.memo 优化 React 组件渲染
在 React 中,性能优化是一个重要的主题,特别是在复杂的组件树中。本文将演示如何在同一个父组件中使用 useMemo 和 React.memo 来优化子组件的渲染。 1. 组件结构 创建一个父组件,包含两个子组件: MemoChild:使用 R…...

ISAAC SIM踩坑记录--添加第三方3D场景
ISAAC SIM仿真首先就是要有合适的3D场景,官方提供了一些场景,如果不能满足要求,那就只能自己建。 对于我这种不会3D建模的菜鸟,只能到网上下载了,sketchfab就是一个不错的平台,有不少免费资源可以下载。 …...
Git 详解
Git 详解 Git 是一个分布式版本控制系统,用于高效地管理项目代码的版本历史。它是目前最流行的版本控制工具之一,广泛应用于软件开发领域。Git 的分布式架构允许开发者在本地进行代码的版本管理,并与远程仓库同步,实现团队协作。…...

Linux操作系统3-文件与IO操作1(从C语言IO操作到系统调用)
上篇文章:Linux操作系统2-进程控制3(进程替换,exec相关函数和系统调用)_execv系统调用-CSDN博客 本篇代码Gitee仓库:myLerningCode 橘子真甜/linux学习 - 码云 - 开源中国 (gitee.com) 本篇重点:C语言基础IO与系统调用 目录 一.…...

【Python网络爬虫笔记】8- (BeautifulSoup)抓取电影天堂2024年最新电影,并保存所有电影名称和链接
目录 一. BeautifulSoup的作用二. 核心方法介绍2.1 构造函数2.2 find()方法2.3 find_all()方法2.4 select()方法 三. 网络爬虫中使用BeautifulSoup四、案例爬取结果 一. BeautifulSoup的作用 解析HTML/XML文档:它可以将复杂的HTML或XML文本转换为易于操作的树形结构…...

Rancher V2.7.0安装教程
1、执行Docker命令 docker run -d --privileged --restartunless-stopped -p 80:80 -p 443:443 -v /home/rancher:/var/lib/rancher --name rancher registry.cn-hangzhou.aliyuncs.com/rancher/rancher:v2.7.0 注:如果容器启动失败,参考我另外一篇文章…...

STM32MX 配置CANFD收发通讯
一、环境 MCU:STM32G0B1CEU6 CAN收发器:JIA1042 二、MX配置 配置SYS 配置canfd并开启中断,我开了两个FDCAN,配置是一样的,这里贴一下波特率的计算公式: 也就是:CAN时钟频率/预分频器/&…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...