news 2026/9/2 16:30:28

LeetCode 34:在排序数组中查找元素的第一个和最后一个位置(含思维过程)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 34:在排序数组中查找元素的第一个和最后一个位置(含思维过程)

题目链接:LeetCode 34 - Find First and Last Position of Element in Sorted Array。leetcode​
题目大意:给定一个按非递减顺序排序的整数数组 nums,和一个目标值 target,要求在数组中找到 target 出现的第一个位置和最后一个位置,返回 [start, end]。如果不存在,返回 [-1, -1],并且算法时间复杂度必须是 O(log⁡n)O(\log n)O(logn)。leetcode​

最朴素的想法:先找到一个,再往两边扫

一开始的直觉很自然:
先用二分查找找到某个 mid,使得 nums[mid] == target。
从 mid 向左扫,直到遇到第一个不等于 target 的位置,前一个就是 start。
从 mid 向右扫,直到遇到第一个不等于 target 的位置,前一个就是 end。
这个思路在正确性上没问题,但有一个明显的问题:
在极端情况下,比如 nums = [8,8,8,8,8,8],虽然找到一个 8 用了 O(log⁡n)O(\log n)O(logn),但是向左、向右的线性扫描又回到了 O(n)O(n)O(n)。
综合起来,最坏复杂度是 O(n)O(n)O(n),不满足题目要求的 O(log⁡n)O(\log n)O(logn)。
所以,向两边"线性扫"是不行的,必须连"找左右边界"这一步也用二分来做。

改进方向:用二分专门找"边界"

既然数组有序,而且要 O(log⁡n)O(\log n)O(logn),自然想到:
不仅要用二分找一个 target,
还要用"改造过的二分"去分别找最左和最右的 target。
这里有两个关键的小问题:
找左边界时,nums[mid] == target 时怎么办?
不能直接返回,因为左边可能还有 target。
正确做法是:记录当前 mid 是一个候选答案,然后把 right 收缩到 mid - 1,继续往左找。
找右边界是不是对称的?
是的,找右边界时,nums[mid] == target 时,记录答案,然后把 left 收缩到 mid + 1,继续往右找。
所以,思路变成:
写一个 find_start_position:
尽量往左压缩,找到"第一个等于 target 的位置"。
写一个 find_end_position:
尽量往右压缩,找到"最后一个等于 target 的位置"。
每个函数内部都是一次完整的二分,整体只做了常数次二分,复杂度是 2⋅log⁡n2 \cdot \log n2⋅logn,在大 O 记号下仍然是 O(log⁡n)O(\log n)O(logn),完全符合要求。enjoyalgorithms+1​

关于"2 次二分是不是超了 O(log n)?"

从渐进复杂度的角度,2⋅log⁡n2 \cdot \log n2⋅logn、3⋅log⁡n3 \cdot \log n3⋅logn 等都写作 O(log⁡n)O(\log n)O(logn),常数因子会被忽略。enjoyalgorithms​
实际上,很多官方题解和主流题解就是 “两次边界二分”:
第一次找左边界;
第二次找右边界;
这一点在面试中是完全没有问题的。

最终实现:两个边界二分函数

下面是用 C 写的完整代码,拆成三个函数:
find_start_position:找左边界。
find_end_position:找右边界。
searchRange:主函数,负责处理空数组、调用两个二分,并返回结果。
代码如下:

intfind_end_position(int*nums,intnumsSize,inttarget){intleft,right,mid,end_position;left=0;right=numsSize-1;end_position=-1;while(left<=right){mid=left+(right-left)/2;if(nums[mid]==target){end_position=mid;left=mid+1;}elseif(nums[mid]<target){left=mid+1;}else{// nums[mid] > targetright=mid-1;}}returnend_position;}intfind_start_position(int*nums,intnumsSize,inttarget){intleft,right,mid,start_position;left=0;right=numsSize-1;start_position=-1;while(left<=right){mid=left+(right-left)/2;if(nums[mid]==target){start_position=mid;right=mid-1;}elseif(nums[mid]<target){left=mid+1;}else{// nums[mid] > targetright=mid-1;}}returnstart_position;}/** * Note: The returned array must be malloced, assume caller calls free(). */int*searchRange(int*nums,intnumsSize,inttarget,int*returnSize){intstart_position,end_position;int*result;result=(int*)malloc(2*sizeof(int));if(!nums||!numsSize){result[0]=-1;result[1]=-1;*returnSize=2;returnresult;}start_position=find_start_position(nums,numsSize,target);end_position=find_end_position(nums,numsSize,target);result[0]=start_position;result[1]=end_position;*returnSize=2;returnresult;}

这份代码在 LeetCode 上可以通过所有用例,实际提交记录:
用例:88 / 88 全部通过。
运行时间:0 ms,击败 100% 提交。
内存使用:9.82 MB。leetcode​

小结:这道题教会了什么?

这道题的关键不在"会不会写二分",而在于:
能否把"找到一个 target"提升为"找到一段 target 的边界";
知道 边界二分的典型写法:命中 target 时不要停,而是继续压缩一端;
能清楚解释为什么"两次二分仍然是 O(log⁡n)O(\log n)O(logn)“;
通过自己一步步把"线性往两边扫"的想法改进为"左右边界都用二分”,是一个很典型的"从直觉解到最优解"的思考路径。
如果想把这个模式记牢,可以再去刷几道类似的"找第一次 / 最后一次出现位置"的题,尽量统一成一套"找左边界 / 右边界"的模板,会在面试里非常加分。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 19:52:48

LobeChat翻译质量测评:中英互译准确度打分

LobeChat翻译质量测评&#xff1a;中英互译准确度打分 在多语言内容爆炸式增长的今天&#xff0c;自动翻译早已不再是“能看就行”的辅助功能&#xff0c;而是决定用户体验、产品出海成败的关键环节。无论是跨国企业发布技术文档&#xff0c;还是独立开发者撰写开源项目说明&am…

作者头像 李华
网站建设 2026/9/2 19:51:24

用EmotiVoice创建多语言情感语音内容的可能性探讨

用EmotiVoice创建多语言情感语音内容的可能性探讨 在虚拟主播直播时突然“变脸”——从温柔知性秒切暴怒模式&#xff0c;语气激烈地控诉弹幕的无理取闹&#xff1b;或是有声书里的角色在悲痛中哽咽、在惊喜时语调上扬&#xff0c;仿佛真人演绎……这些曾属于顶级影视配音的表现…

作者头像 李华
网站建设 2026/9/2 19:50:04

EmotiVoice支持语音风格插值混合吗?实验来了

EmotiVoice支持语音风格插值混合吗&#xff1f;实验来了 在虚拟偶像直播中突然从温柔语调切换到愤怒咆哮&#xff0c;听起来是不是像断了线的木偶&#xff1f;这种情感跳跃的生硬感&#xff0c;正是传统语音合成系统的致命伤。而如今&#xff0c;随着EmotiVoice这类高表现力TT…

作者头像 李华
网站建设 2026/9/2 9:39:45

EmotiVoice技术深度解析:多情感TTS背后的秘密

EmotiVoice技术深度解析&#xff1a;多情感TTS背后的秘密 在虚拟主播动情演绎剧情、游戏NPC因惊险场面脱口而出“小心背后&#xff01;”的今天&#xff0c;我们对机器语音的期待早已超越了“能听清”——用户渴望的是有情绪、有性格、有温度的声音。然而&#xff0c;大多数语音…

作者头像 李华
网站建设 2026/9/2 8:08:12

如何将EmotiVoice集成到现有APP中?移动端适配建议

如何将 EmotiVoice 集成到现有 APP 中&#xff1f;移动端适配建议 在智能手机无处不在的今天&#xff0c;语音交互早已不再是“未来科技”的代名词&#xff0c;而是用户每天都会使用的功能——从导航播报、智能助手到有声书和游戏配音。但你有没有注意到&#xff0c;大多数应用…

作者头像 李华
网站建设 2026/9/2 7:30:05

什么是广域数据消冗

文章目录 为什么需要广域数据消冗广域数据消冗如何工作广域数据消冗的典型应用场景 广域数据消冗将数据压缩技术应用到数据通信网络中&#xff0c;可以对广域网传输的报文进行压缩&#xff0c;不增加带宽消耗的同时&#xff0c;扩大数据的传输量&#xff0c;实现网络建设投资回…

作者头像 李华