LeetCode 算法:在排序数组中查找元素的第一个和最后一个位置 c++
原题链接🔗:在排序数组中查找元素的第一个和最后一个位置
难度:中等⭐️⭐️
题目
给你一个按照非递减顺序排列的整数数组 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
二分查找
-
二分查找(Binary Search),也称为折半搜索,是一种在有序数组中查找特定元素的搜索算法。其基本思想是将目标值与数组中间的元素进行比较:
- 如果目标值等于中间元素,搜索成功,返回该位置。
- 如果目标值小于中间元素,搜索范围缩小至数组的左半部分。
- 如果目标值大于中间元素,搜索范围缩小至数组的右半部分。
- 这个过程将不断重复,直到找到目标值或者搜索范围为空为止。
-
以下是二分查找算法的一般步骤:
-
初始化:设置两个指针,一个指向数组的起始位置(通常记为
left),另一个指向数组的结束位置(通常记为right)。 -
循环条件:当
left小于等于right时,继续循环。 -
计算中间位置:计算
left和right之间的中间位置mid,通常使用(left + right) / 2。 -
比较与调整:
- 如果
nums[mid]等于目标值,根据需要返回mid或继续搜索以找到更精确的位置。 - 如果
nums[mid]大于目标值,将right调整为mid - 1。 - 如果
nums[mid]小于目标值,将left调整为mid + 1。
- 如果
-
循环结束:如果
left大于right,则表示目标值不在数组中,返回一个特定的值(通常是 -1)表示未找到。
-
-
二分查找的效率非常高,时间复杂度为 O(log n),其中 n 是数组的长度。然而,它要求数组是有序的,并且只能应用于一维有序数组。
-
下面是一个简单的 C++ 实现示例:
int binarySearch(const std::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) {return mid; // 找到目标值} else if (nums[mid] < target) {left = mid + 1; // 搜索右半部分} else {right = mid - 1; // 搜索左半部分}}return -1; // 未找到目标值
}
这个函数会返回目标值在数组中的索引,如果目标值不在数组中,则返回 -1。
题解
- 解题思路:
LeetCode 上的这个问题通常被称为“Find First and Last Position of Element in Sorted Array”,题目编号为 34。这个问题可以通过二分查找算法来解决,因为数组是已经排序的。
以下是解决这个问题的一般思路:
理解问题:首先,你需要理解问题的要求,即在一个升序排序的数组中找到给定元素的第一个和最后一个位置。
二分查找:由于数组是有序的,你可以使用二分查找来找到目标元素的索引。二分查找的基本思想是将数组分成两半,比较中间元素与目标值,然后根据比较结果决定是继续在左半部分查找还是右半部分查找。
找到第一个位置:使用二分查找,但需要稍作修改以找到第一个位置。在每次迭代中,如果中间元素等于目标值,你不能立即返回这个位置,因为可能还有更小的索引也是目标值。你需要向左半边继续查找。
找到最后一个位置:同样使用二分查找,但这次如果中间元素等于目标值,你需要向右半边继续查找,因为可能还有更大的索引也是目标值。
边界条件:在查找过程中,需要处理数组的边界条件,确保不会访问数组之外的索引。
- c++ demo:
#include <vector>
#include <iostream>// 二分查找函数,用于找到目标值的索引
int binarySearch(const std::vector<int>& nums, int target, bool findFirst) {int left = 0, right = nums.size() - 1, result = -1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] == target) {result = mid; // 记录找到的位置if (findFirst) {right = mid - 1; // 向左查找第一个位置}else {left = mid + 1; // 向右查找最后一个位置}}else if (nums[mid] < target) {left = mid + 1;}else {right = mid - 1;}}return result;
}// 主函数,用于找到元素的第一个和最后一个位置
std::vector<int> findFirstAndLastPosition(const std::vector<int>& nums, int target) {int first = binarySearch(nums, target, true); // 找到第一个位置int last = binarySearch(nums, target, false); // 找到最后一个位置return { first, last };
}int main() {std::vector<int> nums = { 5, 7, 7, 8, 8, 10 };int target = 8;std::vector<int> positions = findFirstAndLastPosition(nums, target);std::cout << "First position: " << positions[0] << std::endl;std::cout << "Last position: " << positions[1] << std::endl;return 0;
}
- 输出结果:
First position: 3
Last position: 4
- 代码仓库地址:findFirstAndLastPosition
相关文章:
LeetCode 算法:在排序数组中查找元素的第一个和最后一个位置 c++
原题链接🔗:在排序数组中查找元素的第一个和最后一个位置 难度:中等⭐️⭐️ 题目 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标…...
会话存储、本地存储,路由导航守卫、web会话跟踪、JWT生成token、axios请求拦截、响应拦截
1、会话存储、本地存储 前端浏览器中存储用户信息,会话存储、本地存储、cookie 会话存储(sessionStorage):会话期间存储,关闭浏览器后,数据就会销毁 sessionStorage.setItem("account",resp.d…...
strcmp库函数原型
int strcmp(const char *str1, const char *str2) {unsigned const char *s1 (unsigned const char *) str1;unsigned const char *s2 (unsigned const char *) str2;while (*s1 && *s1 *s2) {s1;s2;}return *s1 - *s2; }while (*s1 && *s1 *s2) 一直循环&…...
在 Vue.js 项目中延迟加载子组件
在 Vue.js 中,当父组件渲染时,子组件的生命周期钩子函数会立即执行,即使这些子组件并未显示。这是因为 Vue.js 会在渲染父组件时实例化所有引用的子组件。为了避免不必要的函数执行,我们可以通过使用 v-if 指令和异步组件延迟加载…...
何时会用到设计模式、七大设计原则介绍
以下关于b站尚硅谷相关设计模式视频的总结 设计模式的重要性: 代码重用性(相同的代码,不用编写很多次)、 可读性(编程规范,便于其他程序员阅读和理解)、 可扩展性(增加新功能时&am…...
编程语言发展历史:赋值与相等运算符的变迁历程
本文摘取自笔者书稿《编程语言发展历史》 赋值运算符是编程语言最基础的运算符,其发展历史也非常有趣。最早的赋值语句就是使用等号“”来表示,一些语言为了让赋值运算在数学形式上更加严谨(形如“x x 1”的表达式在数学上不成立࿰…...
求职Leetcode题目(2)
1.柱状图中最大的矩形 据说这是2024年字节二面的题目,我感觉这道题跟接雨水有点类似,最重要的思路还是要找到什么时候能形成矩形的这么个情况,某个范围的矩形的高度,是由最短的柱形来决定的。 我们先整理一下,解决这道…...
深入探索 Postman:使用 API 性能测试优化你的 Web 服务
引言 在当今快速发展的互联网时代,Web 服务的性能至关重要。API 作为服务之间的桥梁,其性能直接影响到整个应用的响应速度和用户体验。Postman,作为一个多功能的 API 开发工具,提供了强大的性能测试功能,帮助开发者评…...
校车购票小程序的设计
管理员账户功能包括:系统首页,个人中心,学生管理,我的乘车信息管理,车辆信息管理,座位管理,系统管理 微信端账号功能包括:系统首页,车辆信息,我的 开发系统…...
拯救数据危机!2024年最受欢迎的数据恢复软件评测
现在大家快速传输资料的方式都变成了电子档,有些数据是存储在电脑上,有些存储在手机,有的存储在U盘甚至其他一些电子设备上。电子设备存储数据方便,丢失数据也总在意料之外。很多时候我们多学会一个工具,比如转转大师数…...
记一次因为在html两个地方引入vue.js导致组件注入失败的问题
这个问题我遇到两次了,是在恼火,不对,三次了,我如果不做这个笔记,我确定我还会遇到第三次。 尾部这个去掉就行 因为头部有了 遇到这种bu g好恼火,解决了又怎么样呢?重蹈覆辙的滋味不好受...
Postman中的智慧重试:API测试用例的错误处理与重试逻辑设置
Postman中的智慧重试:API测试用例的错误处理与重试逻辑设置 在API测试过程中,错误处理和重试逻辑是确保测试准确性和可靠性的重要环节。Postman提供了多种功能来处理测试中可能出现的错误,并允许自定义重试逻辑以适应不同的测试场景。本文将…...
docker部署本地词向量模型
开源项目:GitHub - huggingface/text-embeddings-inference: A blazing fast inference solution for text embeddings models 1. 下载词向量模型 参考我的另一篇博客:langchain 加载本地词向量模型 2. 部署词向量模型 就三行命令 model/data/BAAI/…...
接口自动化中对于文件上传的处理方法
正常的接口自动化基本都是json的格式,对于文件上传是一种特殊的格式是表单格式针对这种表单格式在接口自动化中怎么处理,主要通过工作中使用的一个实际的例子进行分享 举例:web上需要导入一个文件实现相关的功能,主要通过两个接口…...
Java高频面试题分享
文章目录 1. 策略模式怎么控制策略的选取1.1 追问:如果有100种策略呢?1.2 追问:什么情况下初始化Map 2. 什么是索引?什么时候用索引?2.1 追问:怎么判断系统什么时候用量比较少2.2 追问:如何实时…...
kvm虚拟化平台部署
kvm虚拟化平台部署 kvm概念简介 kvm自linux2.6版本以后就整合到内核中,因此可以看做是一个原生架构. kvm虚拟化架构 硬件底层提供物理层面的硬件支持 linux(host),就相当于这个架构中的宿主机,上面运行了多个虚拟机。…...
利用arthas热更新class文件
利用arthas热更新class文件 背景:发现一个bug,家里难以复现,需要在现场环境更新几行代码验证。 arthas-boot version: 3.7.1 java -jar arthas-boot.jar启动arthas 1、利用arthas的sc命令查找确定类名称 sc com.**2、反编译为java文件 …...
天机学堂 第四天 高并发优化总结
前端每隔15秒就发起一次请求,将播放记录写入数据库。 但问题是,提交播放记录的业务太复杂了,其中涉及到大量的数据库操作: 如何进行优化 单机并发能力 变同步为异步 合并写请求 提高单机并发:优化SQL,尽…...
Canva收购Leonardo.ai,增强生成式AI技术能力
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
前端练习<HtmlCSS>——照片墙(附完整代码及实现效果)
这个小练习也来源于b站up小K师兄,大家可以通过下面的链接学习哦~up讲的非常详细。 纯CSS写一个简单酷炫的照片墙效果~ 先看一下这个照片墙的效果: 1.鼠标没有放到图片上时,照片同比例,每张照片都有倒影的效果。 2.然…...
你还在用for循环清洗CSV?Polars 2.0的scan_csv()+expression DSL已支持自动列式推断与零拷贝转换——立即升级避免被淘汰
第一章:Polars 2.0大规模数据清洗的核心范式变革Polars 2.0 不再将数据清洗视为一系列离散的、命令式的转换操作,而是以“惰性执行图列式语义优先”为基石,重构整个清洗生命周期。其核心变革体现在计算模型、内存管理与API设计三重维度的协同…...
如何使用4个经过验证的技巧将Android联系人备份到Mac
联系人无疑是我们智能手机上最重要的数据。一旦失去联系,我们就会与这个世界上最亲爱的人失去联系;也许他们是家人、爱人、朋友、同学、同事、学生等。因此,联系人备份对我们来说非常重要。与将iPhone联系人备份到Mac相对容易不同,…...
5个实战场景掌握DeepSeek-Coder-V2:打造企业级私有化AI编程助手
5个实战场景掌握DeepSeek-Coder-V2:打造企业级私有化AI编程助手 【免费下载链接】DeepSeek-Coder-V2 DeepSeek-Coder-V2: Breaking the Barrier of Closed-Source Models in Code Intelligence 项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Coder-…...
Chrome 安全机制深度解析(二)告别 unsafe-inline:CSP 进阶实战与攻防博弈,构建真正无法绕过的内容防线
配置了 CSP 依然被 XSS 打穿,问题往往不在攻击有多高明,而在于你始终舍不得删掉那两个词:unsafe-inline、unsafe-eval。真正的强安全 CSP,从来不是妥协的产物,而是一套从策略设计到工程落地的完整体系。上一篇我们讲到…...
NVIDIA Profile Inspector终极指南:如何免费解锁显卡隐藏性能
NVIDIA Profile Inspector终极指南:如何免费解锁显卡隐藏性能 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 想要让游戏运行更流畅、画面更清晰吗?NVIDIA显卡驱动中隐藏着大量可…...
【WEB模型】CS架构BS架构HTMLCSSJS
一、CS架构 - Client/Server 客户端/服务器pc安装软件:安卓应用、ios应用需要安装专门软件才能用,软件直接跟服务器通信开发成本高,各个平台都有对应的开发工程师好处:功能强大二、BS架构 - Browser/Server 浏览器/服务器不需要安…...
揭秘冷轧精密带钢DC03-C340:3大核心特性如何赋能精密制造?
朋友们,今天咱们不聊虚的,就聊聊工厂车间里最实在的东西——材料。你是不是也遇到过这样的烦心事:花大价钱买回来的钢带,一上冲床就开裂,废品率居高不下;或者热处理后表面出现诡异的蓝线,抛光怎…...
内网渗透全流程拆解|从入门到实战,小白也能看懂的步骤
内网渗透不是“盲目尝试”,而是遵循固定流程的系统化操作,核心流程可概括为:信息收集→漏洞利用→权限提升→横向移动→权限维持→痕迹清理,每个环节环环相扣,缺一不可。本文将结合小白易理解的实战场景,详…...
Windows 11下Keil5 MDK与C51共存安装全攻略(附ST-Link驱动避坑指南)
Windows 11下Keil5 MDK与C51共存安装全攻略(附ST-Link驱动避坑指南) 在嵌入式开发领域,Keil作为经典开发工具链,其MDK(Microcontroller Development Kit)和C51版本分别服务于ARM架构和8051架构单片机开发。…...
别再让MCSDK电流环PI参数拖后腿了!手把手教你从电机参数到代码配置的完整调参流程
从电机参数到代码实现:MCSDK电流环PI参数优化实战指南 在电机控制领域,电流环的性能直接影响着整个系统的响应速度、稳定性和能效表现。许多工程师在使用STM32的MCSDK进行FOC开发时,往往满足于"电机能转"的基本状态,却忽…...
