找出目标值在数组中的开始和结束位置(二分查找)
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10]
, target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10]
, target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0 输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
方法一:
class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {vector<int> result = {-1, -1};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 - 1;}}if (left < nums.size() && nums[left] == target) {result[0] = left; //找到的话就把起始值记录为left} else {return result; //到了数组结尾还没找到那就直接返回-1,-1}right = nums.size() - 1; //重置 right 为数组的最后一个索引。while (left <= right) { //第二次二分查找int mid = left + (right - left) / 2;if (nums[mid] <= target) { //这里条件不一样需要注意left = mid + 1;} else {right = mid - 1;}}result[1] = right; //更新终止值return result;}
};
这道题可以使用二分查找的原因主要在于题目中的数组是非递减顺序排列的整数数组
vector<int> result = {-1, -1};
初始化一个整数向量 result
,其初始值为 {-1, -1}
。
int mid = left + (right - left) / 2;
计算当前查找范围的中间索引 mid
。这里采用的计算方式是为了避免可能的整数溢出。
if (nums[mid] < target)
:
如果 nums[mid]
小于 target
,说明目标值位于 mid
的右侧,因此将 left
移动到 mid + 1
,缩小查找范围。
如果 nums[mid]
大于或等于 target
,则目标值位于 mid
的左侧(包括 mid
本身),所以将 right
移动到 mid - 1
,缩小查找范围。
left < nums.size()
:
- 这个条件确保
left
不会超出nums
数组的范围。因为left
在查找的过程中可能已经移动到了数组的末尾,如果left
超过了数组的索引范围,直接访问nums[left]
会导致运行时错误。
nums[left] == target
:
- 这个条件检查
nums[left]
是否等于target
。如果left
所指向的元素等于目标值,说明找到了目标值的起始位置。此时,将result[0]
更新为left
,即目标值在数组中的起始索引。
如果 left
不在有效范围内,或者 nums[left]
不等于 target
,这说明数组中不存在目标值。此时直接返回 result
,它的值仍然是 [-1, -1]
,表示未找到目标值。
为什么两次二分查找的 if 语句不一样:
在第一次二分查找中,我们的目标是找到 target
的起始位置。如果存在起始值,当left
和 right
相遇时的相遇点即为起始值 target,这个时候需要保证 left 为 target,就需要right
左移来退出循环。
而在第二次二分查找中,我们的目标是找到 target
的结束位置。我们需要保证right 为 target,就需要 left右移来退出循坏。
二分查找的精髓通过每次比较中间值来逐步缩小查找范围,保证时间复杂度为 O(logn)
方法二:
class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int start = find(nums, target);int end = find(nums, target + 1) - 1;if (start == -1 || end < start) {return {-1, -1};}return {start, end};}int find(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;} else {right = mid - 1;}}return left;}
};
利用 find(nums, target)
找到 target
的第一个位置,再利用 find(nums, target + 1)
找到比 target
大的第一个元素的位置,从而间接确定 target
的结束位置。
如果数组中不存在第一个大于 target
的元素,那么 find(nums, target + 1)
的结果将会是 nums.size(),
end的值为 nums.size() - 1
假设 nums = [5, 7, 7, 8, 8, 10]
,target = 8
:
find(nums, 8)
返回3
,因为8
的第一个位置在索引3
。find(nums, 9)
返回5
,因为9
比8
大,且索引5
是第一个大于8
的位置。end = find(nums, 9) - 1
等于4
,所以返回[3, 4]
。
相关文章:
找出目标值在数组中的开始和结束位置(二分查找)
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示例 1:…...
VSCode进阶之路
VSCode进阶之路:从入门到高效率开发 🚀 Hey,朋友们好!还在为VSCode的海量功能感到眼花缭乱吗?咱们一起来解锁VSCode的超神技能吧! 开篇碎碎念 🎯 第一次用VSCode时,就像个闯入魔法世…...

leetcode-21-合并两个有序链表
题解: 1、初始化哑节点dum 2、 3、 代码: 参考:leetcode-88-合并两个有序数组...

SSM项目部署到服务器
将SSM(Spring Spring MVC MyBatis)项目部署到服务器上,通常需要以下步骤: 打包项目 生成一个WAR文件,通常位于target目录下 配置Tomcat: 将生成的WAR文件复制到Tomcat的webapps目录下。 配置conf/se…...

【Linux】网络编程:初识协议,序列化与反序列化——基于json串实现,网络通信计算器中简单协议的实现、手写序列化与反序列化
目录 一、什么是协议? 二、为什么需要有协议呢? 三、协议的应用 四、序列化与反序列化的引入 什么是序列化和反序列化? 为什么需要序列化和反序列化? 五、序列化推荐格式之一:JSON介绍 六、网络版计算器编程逻…...
Educational Codeforces Round 171 (Rated for Div. 2)(A~D) 题解
Problem - A - Codeforces--PerpendicularSegments 思路:正方形对角线最长,并且相互垂直.直接输出即可. int x,y,k; void solve(){ //Acin>>x>>y>>k;int resmin(x,y);cout<<"0 0"<<" "<<res<<" &q…...

【教程】Git 标准工作流
目录 前言建仓,拉仓,关联仓库修改代码更新本地仓库,并解决冲突提交代码,合入代码其他常用 Git 工作流删除本地仓库和远程仓库中的文件日志打印commit 相关 前言 Git 是日常开发中常用的版本控制工具,配合代码托管仓库…...

Nico,从零开始干掉Appium,移动端自动化测试框架实现
开头先让我碎碎念一波~去年差不多时间发布了一篇《 UiAutomator Nico,一个基于纯 adb 命令实现的安卓自动化测试框》(https://testerhome.com/topics/37042), 由于种种原因 (详见此篇帖子) 当时选择了用纯 adb 命令来实现安卓自动…...

PHP合成图片,生成海报图,poster-editor使用说明
之前写过一篇使用Grafika插件生成海报图的文章,但是当我再次使用时,却发生了错误,回看Grafika文档,发现很久没更新了,不兼容新版的GD,所以改用了intervention/image插件来生成海报图。 但是后来需要对海报…...
微信小程序 - 数组 push / unshift 追加后数组返回内容为数字(数组添加后打印结果为 Number 数值类型)
前言 假设一个空数组,通过 push 方法追加了一个项,控制台打印的结果竟然是 Number 数值。 例如,以下微信小程序代码: // 源数组 var arr = [] // 追加数据 var tem = arr.push(数据)...

1、DevEco Studio 鸿蒙仓颉应用创建
1. 仓颉鸿蒙应用简介 因为仓颉是静态编译型语言,使用仓颉开发的应用执行效率更高。而且主打全场景,后续可并入仓颉生态,其和ArkTS都是基于ArkUI进行开发,最大的区别是typescript和仓颉语法间的差异。 2. 应用创建 前置条件&…...

从头开始学PHP之面向对象
首先介绍下最近情况,因为最近入职了且通勤距离较远,导致精力不够了,而且我发现,人一旦上了班,下班之后就不想再进行任何脑力劳动了(对大部分牛马来说,精英除外)。 话不多说进入今天的…...

C++ | Leetcode C++题解之第519题随机翻转矩阵
题目: 题解: class Solution { public:Solution(int m, int n) {this->m m;this->n n;this->total m * n;srand(time(nullptr));}vector<int> flip() {int x rand() % total;vector<int> ans;total--; // 查找位置 x 对应的…...

vrrp和mstp区别
思路 vrrp是用来虚拟网关,噢,是虚拟一条虚拟网关 优先级,priority越大越优先,优先级相同,哪个的路由器的vrrp先起来,谁就是主 mstp是快速生成树协议,防止环路用的 优先级越小越优先 华为命令…...

前端页面整屏滚动fullpage.js简单使用
官网CSS,JS地址 fullPage.js/dist/fullpage.min.js at master alvarotrigo/fullPage.js GitHub fullPage.js/dist/fullpage.min.css at master alvarotrigo/fullPage.js GitHub <!DOCTYPE html> <html lang"en"><head><meta charset"…...

JQuery基本介绍和使用方法
JQuery基本介绍和使用方法 W3C 标准给我们提供了⼀系列的函数, 让我们可以操作: ⽹⻚内容⽹⻚结构⽹⻚样式 但是原⽣的JavaScript提供的API操作DOM元素时, 代码⽐较繁琐, 冗⻓. 我们可以使⽤JQuery来操作⻚⾯对象. jQuery是⼀个快速、简洁且功能丰富的JavaScript框架, 于20…...

【案例】旗帜飘动
开发平台:Unity 6.0 开发工具:Shader Graph 参考视频:Unity Shader Graph 旗帜飘动特效 一、效果图 二、Shader Graph 路线图 三、案例分析 核心思路:顶点偏移计算 与 顶点偏移忽略 3.1 纹理偏移 视觉上让旗帜保持动态飘动&a…...

大模型思维链推理的综述:进展、前沿和未来
转自公众号AIRoobt A Survey of Chain of Thought Reasoning: Advances, Frontiers and Future 思维链推理的综述:进展、前沿和未来 摘要:思维链推理,作为人类智能的基本认知过程,在人工智能和自然语言处理领域引起了极大的关注…...

项目一:使用 Spring + SpringMVC + Mybatis + lombok 实现网络五子棋
一:系统展示: 二:约定前后端接口 2.1 登陆 登陆请求: GET /login HTTP/1.1 Content-Type: application/x-www-form-urlencodedusernamezhangsan&password123登陆响应: 正常对象:正常对象会在数据库中存储&…...
openEuler 系统中 Samba 文件共享服务器管理(windows、linux文件共享操作方法)
一、Samba 简介 Samba 是在 Linux 和 Unix 系统上实现 SMB/CIFS 协议的一个免费软件,使得这些系统可以与 Windows 系统进行文件和打印机共享。通过 Samba,可以将 openEuler 系统配置为文件服务器,让 Windows、Linux 和其他支持 SMB/CIFS 协议…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...