二分查找算法实战:在有序数组中查找元素范围
1. 题目解析与核心需求力扣第65题在排列数组中查找元素的第一个和最后一个位置是二分查找算法的经典应用场景。给定一个按照非递减顺序排列的整数数组nums和一个目标值target需要找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值则返回[-1, -1]。这个题目看似简单但考察了几个关键点对二分查找算法的深入理解处理边界条件的严谨性对时间复杂度的控制要求(O(log n))对数组特性的充分利用在实际编程面试中这道题经常被用作考察候选人对基础算法的掌握程度和编码细节处理能力。很多初学者容易陷入找到目标值就万事大吉的误区而忽略了题目要求的是查找范围而非单个位置。2. 算法思路与设计2.1 二分查找的变体应用标准的二分查找算法在找到目标值后会立即返回但本题需要找到目标值的边界。因此我们需要对标准二分查找进行两次改造查找第一个等于target的位置查找最后一个等于target的位置对于查找第一个位置当nums[mid] target时我们仍需继续向左搜索检查是否还有更早出现的target。同理查找最后一个位置时需要继续向右搜索。2.2 边界条件处理这道题最容易出错的地方在于各种边界条件的处理数组为空的情况目标值不存在于数组中的情况目标值恰好是数组第一个或最后一个元素的情况数组中所有元素都相同且等于目标值的情况在实际编码时需要特别注意循环条件(while left right还是while left right)以及指针移动方式(right mid还是right mid - 1)这些细节往往决定了算法的正确性。3. 详细实现步骤3.1 查找第一个位置的实现def find_first(nums, target): left, right 0, len(nums) - 1 first -1 while left right: mid left (right - left) // 2 if nums[mid] target: first mid right mid - 1 # 继续向左搜索 elif nums[mid] target: left mid 1 else: right mid - 1 return first3.2 查找最后一个位置的实现def find_last(nums, target): left, right 0, len(nums) - 1 last -1 while left right: mid left (right - left) // 2 if nums[mid] target: last mid left mid 1 # 继续向右搜索 elif nums[mid] target: left mid 1 else: right mid - 1 return last3.3 组合完整解法def searchRange(nums, target): first find_first(nums, target) if first -1: return [-1, -1] last find_last(nums, target) return [first, last]4. 时间复杂度分析与优化4.1 时间复杂度由于我们进行了两次二分查找每次的时间复杂度都是O(log n)因此总时间复杂度仍然是O(log n)。这满足了题目对时间复杂度的要求。4.2 空间复杂度算法只使用了常数级别的额外空间空间复杂度为O(1)。4.3 可能的优化方向虽然上述解法已经足够高效但还可以考虑以下优化在一次二分查找中同时记录第一个和最后一个位置减少常数因子使用更简洁的循环条件和指针更新方式提前终止条件如果第一次查找就返回-1可以直接返回[-1, -1]而无需第二次查找5. 常见错误与调试技巧5.1 典型错误案例死循环由于循环条件或指针更新不当导致的无限循环边界错误未能正确处理数组边界情况漏判情况当目标值不存在时返回错误结果重复计算不必要的重复操作导致性能下降5.2 调试方法使用小规模测试用例手动模拟算法执行过程打印关键变量值left, right, mid等观察变化测试边界条件空数组、单元素数组、全相同元素数组等使用力扣的测试用例功能验证各种情况5.3 测试用例设计好的测试用例应该包含常规情况目标值在数组中间边界情况目标值是第一个或最后一个元素特殊情况数组中不存在目标值极端情况数组所有元素都相同空数组情况单元素数组情况例如输入nums [5,7,7,8,8,10], target 8 输出[3,4] 输入nums [5,7,7,8,8,10], target 6 输出[-1,-1] 输入nums [], target 0 输出[-1,-1] 输入nums [1,1,1,1], target 1 输出[0,3]6. 实际应用与扩展6.1 实际应用场景这种查找元素范围的算法在实际开发中有广泛应用日志系统中查找特定时间范围内的事件数据库查询中查找某个值段的记录统计分析中确定某个值的分布区间版本控制系统中查找某个特性的引入和移除范围6.2 算法扩展基于这个算法思想可以解决更多类似问题统计有序数组中某个值出现的次数last - first 1查找有序数组中离给定值最近的元素在旋转排序数组中查找目标值在二维矩阵中查找目标值6.3 力扣相关题目推荐为了巩固二分查找算法可以尝试以下力扣题目第34题在排序数组中查找元素的第一个和最后一个位置本题第35题搜索插入位置第74题搜索二维矩阵第153题寻找旋转排序数组中的最小值第162题寻找峰值第278题第一个错误的版本7. 编码风格与最佳实践7.1 代码可读性建议使用有意义的变量名如first_pos、last_pos比简单的left、right更易理解添加适当的注释说明算法关键步骤将辅助函数分离保持主函数简洁统一缩进和代码风格7.2 防御性编程添加输入参数检查处理可能的异常情况添加类型提示Python编写单元测试验证各种边界条件7.3 性能考量避免在循环内进行不必要的计算减少函数调用开销选择合适的数据结构利用语言特性优化性能8. 不同语言实现对比8.1 Python实现特点Python实现简洁明了利用列表切片和动态类型可以写出非常简洁的代码。但需要注意Python的整数除法使用//运算符列表索引越界会抛出异常需要特别注意动态类型可能导致一些隐式错误8.2 Java实现特点Java实现通常更严谨需要处理更多细节明确的类型声明数组长度通过length属性获取需要处理整数溢出问题mid计算8.3 C实现特点C实现可以非常高效但需要注意指针和迭代器的使用标准库提供的二分查找函数更严格的内存管理9. 面试技巧与注意事项9.1 面试中如何应对此题先明确问题要求确认输入输出格式讨论可能的解决方案和它们的时间复杂度选择最优方案并解释选择理由边写代码边解释思路写完代码后主动测试几个用例9.2 常见面试问题面试官可能会问为什么选择二分查找而不是线性扫描如何处理重复元素的情况算法的时间复杂度是多少如何证明如果数组非常大这个算法还适用吗如何修改算法来统计目标值出现的次数9.3 代码审查要点在代码审查时应注意边界条件处理是否正确循环条件是否会导致死循环或提前退出变量命名是否清晰代码是否有冗余或可以优化的部分是否有注释解释复杂逻辑10. 学习资源与进阶路径10.1 推荐学习资料《算法导论》中的二分查找章节力扣二分查找专题各大高校的算法公开课如MIT 6.006经典算法书籍中的相关章节10.2 练习建议从简单题目开始逐步提高难度每道题尝试多种解法并比较优劣总结常见模式和技巧参加编程竞赛锻炼实战能力10.3 学习路线图建议的学习路径掌握标准二分查找算法理解各种二分查找变体练习相关题目积累经验学习如何分析算法复杂度应用到实际问题中

相关新闻

Wireshark统计功能实战:从海量流量中快速定位攻击者IP

Wireshark统计功能实战:从海量流量中快速定位攻击者IP

1. 项目概述:从海量数据中揪出“捣蛋鬼” 刚接触CTF(Capture The Flag)或者网络安全分析的朋友,最头疼的恐怕就是拿到一个动辄几百MB甚至上GB的“大流量包”了。面对成千上万条网络数据流,感觉就像被扔进了一个嘈杂无比…

2026/10/18 12:06:29 阅读更多 →
高效获取九大网盘直链:LinkSwift完整使用指南

高效获取九大网盘直链:LinkSwift完整使用指南

高效获取九大网盘直链:LinkSwift完整使用指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅…

2026/10/19 15:44:06 阅读更多 →
WSA Toolbox终极指南:如何在Windows 11上轻松运行Android应用

WSA Toolbox终极指南:如何在Windows 11上轻松运行Android应用

WSA Toolbox终极指南:如何在Windows 11上轻松运行Android应用 【免费下载链接】wsa-toolbox A Windows 11 application to easily install and use the Windows Subsystem For Android™ package on your computer. 项目地址: https://gitcode.com/gh_mirrors/ws/…

2026/10/20 0:17:08 阅读更多 →

最新新闻

基于websocket++的C++ WebSocket通信demo与二次开发实战

基于websocket++的C++ WebSocket通信demo与二次开发实战

简介:基于WebSocket构建的客户端与服务端示例代码包,面向需要在C项目中快速实现实时双向通信的开发者,尤其适合结合Boost在Windows环境下搭建WebSocket应用的初学者。压缩包共2000个文件,大小约320.48MB,内容以hpp头文…

2026/10/20 12:04:00 阅读更多 →
【基于 Swoole+Hyperf 的微服务实战】第十一周 · 周四:异常检测---简单阈值告警与规则引擎

【基于 Swoole+Hyperf 的微服务实战】第十一周 · 周四:异常检测---简单阈值告警与规则引擎

今天我们进入第十一周周四,主题是 异常检测:简单阈值告警与规则引擎。在之前的统计基础上,我们已经能够实时查看 UV/PV,但被动观察不够,我们需要系统主动发现异常并通知我们。今天将在日志消费者中加入实时异常检测能力…

2026/10/20 12:04:00 阅读更多 →
C# WinForms 鼠标拖动控件原理与工程落地:偏移量、事件循环与边界约束

C# WinForms 鼠标拖动控件原理与工程落地:偏移量、事件循环与边界约束

简介:面向C# WinForm开发者的鼠标拖动控件完整工程源码,演示了在窗体中通过MouseDown、MouseMove、MouseUp三个事件实现控件自由拖拽的核心逻辑,涵盖鼠标状态检测、屏幕坐标到控件坐标的转换、Location更新定位及父容器边界限制等关键处理。压…

2026/10/20 12:04:00 阅读更多 →
U-Net图像分割实战:从原理到部署的完整指南

U-Net图像分割实战:从原理到部署的完整指南

1. U-Net为什么能打:核心设计思路拆解做图像分割的同行应该都有同感:U-Net这名字听起来朴素得像某个临时工写的工具函数,但它硬是从2015年火到现在,十多年过去了,依然是很多场景下的首选基线。我自己最早接触它是在某个…

2026/10/20 12:04:00 阅读更多 →
汇编视角下的变量内存布局:全局与局部变量的本质区别

汇编视角下的变量内存布局:全局与局部变量的本质区别

1. 这不是“黑客教程”,而是一份写给真正想搞懂程序底层的人的汇编变量手记你点开这个标题,大概率不是为了找一个能绕过某款软件验证的“万能钥匙”,也不是冲着“秒破XX保护”这类标题党来的。如果你是刚啃完《深入理解计算机系统》前五章、在…

2026/10/20 12:04:00 阅读更多 →
AI辅助毕业答辩PPT制作:逻辑压缩与实操全攻略

AI辅助毕业答辩PPT制作:逻辑压缩与实操全攻略

每年四五月份,总有一批人要熬夜改答辩PPT。我当年也没躲过这关——论文写完了,数据跑完了,结果卡在“怎么把几十页Word变成十几页PPT”上,一页页截图、复制、删减、调整格式,那几天基本是崩溃的。现在情况好多了&#…

2026/10/20 12:02:59 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →