二分查找——经典题目合集

文章目录
- 🦜69. x 的平方根
- 🌼题目
- 🌻算法原理
- 🌷代码实现
- 🐳35. 搜索插入位置
- 🌼题目
- 🌻算法原理
- 🌷代码实现
- 🦭852. 山脉数组的峰顶索引
- 🌼题目
- 🌻算法原理
- 代码实现
- 🐧162. 寻找峰值
- 🌼题目
- 🌻算法原理
- 🌷代码实现
- 🦚153. 寻找旋转排序数组中的最小值
- 🌼题目
- 🌻算法原理
- 🌷代码实现
- 🦖LCR 173. 点名
- 🌼题目
- 🌻算法原理
- 🌷代码实现
704.二分查找、34. 在排序数组中查找元素的第一个和最后一个位置(二分查找模板)
🦜69. x 的平方根
🌼题目
题目链接:69. x 的平方根 - 力扣(LeetCode)
给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意: 不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
示例 1:
输入:x = 4
输出:2
示例 2:
输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 231 - 1
🌻算法原理
本题采用二分查找,题目给的x,要求是有符合的平方根就返回该x的平方根,如果没有则返回小于它的整数平方根

🌷代码实现
class Solution {
public: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; //long long防止溢出if(mid*mid <= x) left = mid;else right = mid-1;}return left;}
};
🐳35. 搜索插入位置
🌼题目
题目链接:35. 搜索插入位置 - 力扣(LeetCode)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为O(log n)的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
1 <= nums.length <= 104-104 <= nums[i] <= 104nums为 无重复元素 的 升序 排列数组-104 <= target <= 104
🌻算法原理
本题要求是如果找到目标值,则返回下标;如果找不到,则返回要填入的位置

🌷代码实现
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) return left+1;return left;}
};
🦭852. 山脉数组的峰顶索引
🌼题目
题目链接:852. 山脉数组的峰顶索引 - 力扣(LeetCode)
符合下列属性的数组 arr 称为 山脉数组 :
arr.length >= 3- 存在
i(0 < i < arr.length - 1)使得:arr[0] < arr[1] < ... arr[i-1] < arr[i]arr[i] > arr[i+1] > ... > arr[arr.length - 1]
给你由整数组成的山脉数组 arr ,返回满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i 。
你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:
输入:arr = [0,2,1,0]
输出:1
示例 3:
输入:arr = [0,10,5,2]
输出:1
提示:
3 <= arr.length <= 1050 <= arr[i] <= 106- 题目数据保证
arr是一个山脉数组
🌻算法原理
题目说了,这些数据必是一个山峰数组,所以我们可以直接暴力的将其遍历,找出前一个数小于当前数的位置,但有个要求是时间复杂度为O(log(n)) 。
由于这个数组必是山峰数组,那么它是具有二段性的,所以我们可以采用二分查找

代码实现
class Solution {
public:int peakIndexInMountainArray(vector<int>& arr) {int left = 1; //初始位置和末尾位置必不可能是峰顶int right = arr.size()-1 -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;}
};
🐧162. 寻找峰值
🌼题目
题目链接:162. 寻找峰值 - 力扣(LeetCode)
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
示例 1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;或者返回索引 5, 其峰值元素为 6。
提示:
1 <= nums.length <= 1000-231 <= nums[i] <= 231 - 1- 对于所有有效的
i都有nums[i] != nums[i + 1]
🌻算法原理
我们可以暴力解法,遍历这个数组,如果开始下降,则可以返回该位置的值;如果一直向上,则返回最后一个位置的即可。这里最坏的情况就是走到最后一个位置,时间复杂度为O(N)。

在此基础上,我们可以优化这个暴力解法,我们抽象这个数组:
-
选定某
i位置,当前位置大于i+1,此时是一个下降区域,那么在i的左边区域,肯定会有一个上升区域(因为左右都是负无穷),而右边区域不一定有结果,因为右边也是负无穷,可能会一直下降到负无穷大
-
如果选的的
i位置,小于i+1位置的元素,那么这个区域此时是一个上升区域,那么在i的右边区域,肯定会有一个下降区域

通过这两种情况的抽象,虽然这个数组是一个完全无序的数组,但是它具有二段性,那么我们就可以采用二分查找的思想

🌷代码实现
class Solution {
public: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;elseleft = mid+1;}return left;}
};
🦚153. 寻找旋转排序数组中的最小值
🌼题目
题目链接:153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
- 若旋转
4次,则可以得到[4,5,6,7,0,1,2] - 若旋转
7次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。
给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
示例 2:
输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。
示例 3:
输入:nums = [11,13,15,17]
输出:11
解释:原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
提示:
n == nums.length1 <= n <= 5000-5000 <= nums[i] <= 5000nums中的所有整数 互不相同nums原来是一个升序排序的数组,并进行了1至n次旋转
🌻算法原理
这就只有一个数组,我们可以直接暴力求解,直接遍历整个数组,找出最小值,直接遍历的时间复杂度为O(N)。
由于题目说这是一个预先有序的数组,旋转得到的,所以这个数组是有二段性的

- 在
A~B区域:nums[i] > nums[n-1] - 在
C~D区域:nums[i] <= nums[n-1]

🌷代码实现
class Solution {
public:int findMin(vector<int>& nums){int left = 0;int right = nums.size()-1;int t = nums[right];while(left<right){int mid = left+(right-left)/2;if(nums[mid]>t)left = mid+1;elseright = mid;}return nums[left];}
};
🦖LCR 173. 点名
🌼题目
题目链接:LCR 173. 点名 - 力扣(LeetCode)
某班级 n 位同学的学号为 0 ~ n-1。点名结果记录于升序数组 records。假定仅有一位同学缺席,请返回他的学号。
示例 1:
输入: records = [0,1,2,3,5]
输出: 4
示例 2:
输入: records = [0, 1, 2, 3, 4, 5, 6, 8]
输出: 7
提示:
1 <= records.length <= 10000
🌻算法原理
这题还是比较简单,但是有很多种方法
- 哈希表
- 直接遍历
- 位运算
- 高斯求和
这四种解法,时间复杂度都是O(N)
该题目说,学号从0开始,那么在断开之前,整个数组对应的下标和元素是相等的,从断开位置开始,元素都是比下标大1的,这又出现了二段性,那么就可以采用二分查找

有可能整个数组完全不缺,例如
0,1,2,3那么我们缺少的就是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;elseright = mid;}return records[left]==left?left+1:left;}
};
相关文章:
二分查找——经典题目合集
文章目录 🦜69. x 的平方根🌼题目🌻算法原理🌷代码实现 🐳35. 搜索插入位置🌼题目🌻算法原理🌷代码实现 🦭852. 山脉数组的峰顶索引🌼题目🌻算法原…...
在Jupyter Lab中使用多个环境,及魔法命令简介
一、Jupyter Lab使用conda虚拟环境 1、给虚拟环境添加 ipykernel 方法一: 创建环境时直接添加ipykernel 方法:conda create -n 【虚拟环境名称】python3.8 ipykernel实例如下: conda create -n tensorflow_cpu python3.8 ipykernel 方法二ÿ…...
知虾数据软件:电商人必备知虾数据软件,轻松掌握市场趋势
在当今数字化时代,数据已经成为了企业决策的重要依据。对于电商行业来说,数据更是至关重要。如果你想在电商领域中脱颖而出,那么你需要一款强大的数据分析工具来帮助你更好地了解市场、分析竞争对手、优化运营策略。而知虾数据软件就是这样一…...
c语言中*p1++和p1++有啥区别
在C语言中,*p1和p1是两个不同的表达式,有以下区别: *p1:这是一个后缀递增运算符的组合。首先,*p1会取出指针p1所指向的值,并且对p1进行递增操作。简而言之,这个表达式会先取出p1指向的值&#x…...
2
【任务 2】私有云服务运维[10 分] 【适用平台】私有云 【题目 1】OpenStack 开放镜像权限[0.5 分] 使 用 OpenStack 私 有 云 平 台 , 在 OpenStack 平台的 admin 项 目 中 使 用 cirros-0.3.4-x86_64-disk.img 镜像文件创建名为 glance-cirros 的镜像,通…...
SELinux零知识学习二十二、SELinux策略语言之类型强制(7)
接前一篇文章:SELinux零知识学习二十一、SELinux策略语言之类型强制(6) 二、SELinux策略语言之类型强制 3. 访问向量规则 AV规则就是按照对客体类别的访问许可指定具体含义的规则,SELinux策略语言目前支持四类AV规则:…...
cadence layout lvs时出现error
Error:Schematic export failed or was cancelled.Please consult the transcript in the viewer window. 解决办法同下: cadence layout lvs时出现error-CSDN博客...
python练习题(markdown中的60道题)
1.Demo01 摄氏温度转化为华氏温度 celsius float(input(输入摄氏温度:)) fahrenheit (9/5)*celsius 32 print(%0.1f 摄氏温度转为华氏温度为 %0.1f % (celsius, fahrenheit))结果: 2.Demo02 计算圆柱体的体积 h, r map(float, input().split())# …...
【JavaSE】-4-单层循环结构
回顾 运算符: 算术 --、逻辑 && & || |、比较 、三元 、赋值 int i 1; i; j i; //j2 i3 syso(--j"-----"i) //1 3 选择结构 if(){} if(){}else{} if(){}else if(){}else if(){}else{}//支持byte、short、int //支持char //支持枚举…...
12、人工智能、机器学习、深度学习的关系
很多年前听一个机器学习的公开课,在Q&A环节,一个同学问了老师一个问题“机器学习和深度学习是什么关系”? 老师先没回答,而是反问了在场的同学,结果问了2-3个,没有人可以回答的很到位,我当时也是初学一脸懵,会场准备的小礼品也没有拿到。 后来老师解释“机器学习和…...
webpack external 详解
作用:打包时将依赖独立出来,在运行时(runtime)再从外部获取这些扩展依赖,目的时解决打包文件过大的问题。 使用方法: 附上代码块 config.set(externals, {vue: Vue,vue-router: VueRouter,axios: axios,an…...
代码混淆不再愁:一篇掌握核心技巧
1. 概述 代码混淆是将计算机程序的代码转换成一种功能上等价,但是难以阅读和理解的形式。 对于软件开发者来说,代码混淆可以在一定程度上保护程序免被逆向。 对于逆向工程师来说,学习代码混淆可以帮助我们研究反混淆技术。 2. 常见混淆…...
华为云IoT与OpenHarmony深度协同,加速设备上鸿即上云【云驻共创】
本次专题论坛探讨了华为云IoT与Open Harmony的深度协同、边缘屏蔽硬件差异、实现智慧隧道全方位智能化管理,以及华为云与Open Harmony生态的合作。同时也介绍了华为云物联网卡平台、HTTP2协议以及华为物联网在交通领域的应用。 一.华为云IoT与Open Harm…...
深入浅出 Linux 中的 ARM IOMMU SMMU I
Linux 系统下的 SMMU 介绍 在计算机系统架构中,与传统的用于 CPU 访问内存的管理的 MMU 类似,IOMMU (Input Output Memory Management Unit) 将来自系统 I/O 设备的 DMA 请求传递到系统互连之前,它会先转换请求的地址,并对系统 I…...
关于sqlModel 实现查询表单入参空值和模糊匹配一次性查询
在处理表单提交后,后端 SQL 查询部分空值和部分模糊值时,可以使用 SQLModel 构建动态查询。你可以根据表单数据动态构建 SQL 查询,并且只添加那些非空的、有值的条件。 以下是一个示例,假设你有一个模型 Item: from …...
数据仓库架构之详解Kappa和Lambda
目录 一、前言 二、架构详解 1 Lambda 架构 1.1 Lambda 架构组成 1.2 Lambda 特点 1.3 Lambda 架构的优点 1.4 Lambda 架构的不足 2 Kappa 架构 2.1 Kappa 架构的核心组件 2.2 Kappa 架构优点 2.3 Kappa 架构的注意事项 三、区别对比 四、选择时考虑因素 一、前言 …...
Banana Pi BPI-R3 Mini 开源路由器,也能拍出艺术美感
香蕉派BPI-R3 Mini路由器板开发板采用联发科MT7986A(Filogic 830)四核ARM A53芯片设计,板载2G DDR 内存,8G eMMC和128MB SPI NAND存储,是一款非常高性能的开源路由器开发板,支持Wi-Fi6 2.4G/5G(MT7976C)&am…...
Django高级之-分页器
目录 一、引入 二、分页推导 三、数据总页面获取 四、内置方法之divmod 五、终极大法 六、自定义分页器使用 【1】后端 【2】前端 一、引入 针对上一小节批量插入的数据 我们在前端展示的时候发现一个很严重的问题一页展示了所有的数据,数据量太大…...
Vue-报错No “exports“ main defined in xx
vue报错:No "exports" main defined in F:\wjh\vue#Practice\EasyQuestionnaire-web-master\EasyQuestionnaire-web-master\node_modules\babel\helper-compilation-targets\package.json 1.在文件中找到该路径的package.json文件, 2.按照提示…...
EL-input添加双击或者单击事件
#El-lement UI # 这个框架确实给我们带来了很多好处,最近一直忙于项目,没时间来写文章,最近有个问题困扰我很久,最终却很简单的解决了,记下来希望能帮助更多的人。 大家都知道el-input是无法直接添加click或者dblcli…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...
