当前位置: 首页 > news >正文

LeetCode 35. 搜索插入位置:二分查找的边界条件深度解析

文章目录

    • 问题描述
    • 方法思路:二分查找
      • 1. 初始化指针
      • 2. 循环条件与中间值计算
      • 3. 调整指针范围
      • 4. 确定插入位置
    • 解决代码
    • 代码解释
    • 常见问题
      • 1. 为什么循环条件必须是 `left <= right`,用 `left < right` 会报错?
      • 2. 如何处理重复元素?
      • 3. 时间复杂度与空间复杂度
    • 总结

摘要
本文详细解析 LeetCode 35 题《搜索插入位置》的解题思路,重点探讨二分查找中循环条件 left <= right 的必要性,并提供 Java 实现代码。通过边界案例分析和常见错误解答,帮助读者深入理解二分查找的边界处理逻辑。


问题描述

给定一个升序排列的整数数组 nums 和一个目标值 target,要求找到 target 在数组中的插入位置。若 target 已存在于数组中,则返回其索引;否则返回其按升序插入的位置。
示例

  • 输入:nums = [1,3,5,6], target = 5 → 输出:2
  • 输入:nums = [1,3,5,6], target = 2 → 输出:1

方法思路:二分查找

二分查找是解决有序数组搜索问题的经典算法,其核心是通过不断缩小搜索范围定位目标值。以下是具体步骤:

1. 初始化指针

  • left:指向数组起始位置(0)。
  • right:指向数组末尾位置(nums.length - 1)。

2. 循环条件与中间值计算

  • 循环条件:使用 left <= right 确保所有元素都被检查。
  • 中间值计算mid = left + (right - left) / 2(避免整数溢出)。

3. 调整指针范围

  • nums[mid] == target:直接返回 mid
  • nums[mid] < target:说明目标值在右半部分,调整 left = mid + 1
  • nums[mid] > target:说明目标值在左半部分,调整 right = mid - 1

4. 确定插入位置

循环结束时,left 指向第一个大于 target 的元素位置,或数组末尾(即插入位置)。


解决代码

class Solution {public int searchInsert(int[] nums, int target) {int left = 0, right = nums.length - 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 left;  // left 是第一个大于 target 的位置}
}

代码解释

代码片段说明
int left = 0, right = nums.length - 1初始化指针,覆盖整个数组范围。
while (left <= right)关键点:保证所有元素被检查,尤其是 left == right 的情况。
mid = left + (right - left) / 2防止 (left + right) 导致的整数溢出。
if (nums[mid] == target)找到目标值,直接返回索引。
left = mid + 1 / right = mid - 1缩小搜索范围,逐步逼近目标位置。
return left循环结束时,left 指向插入位置。

常见问题

1. 为什么循环条件必须是 left <= right,用 left < right 会报错?

  • 错误示例:数组 [5],目标值 7

    • 若使用 left < right,循环不会执行,直接返回 left = 0(错误)。
    • 正确插入位置应为 1
  • 根本原因
    left < rightleft == right 时跳过循环,导致最后一个元素未被检查。此时:

    • 若目标值等于最后一个元素,无法返回正确索引。
    • 若目标值大于最后一个元素,错误返回 left 而非 left + 1

2. 如何处理重复元素?

  • 若存在多个 target,返回第一个匹配的索引(因升序数组的特性,二分查找天然优先定位到左侧)。

3. 时间复杂度与空间复杂度

  • 时间复杂度O(log n),二分查找每次缩小一半搜索范围。
  • 空间复杂度O(1),仅使用常数级别额外空间。

总结

  • 核心技巧:正确使用 left <= right 循环条件,确保所有边界情况被覆盖。
  • 适用场景:有序数组的搜索、插入位置问题(如 LeetCode 34、278、704 题)。
  • 扩展思考:若数组为降序排列,如何调整比较逻辑?

题目链接:LeetCode 35. 搜索插入位置

http://www.xdnf.cn/news/508843.html

相关文章:

  • nginx概念及使用
  • 分别用 语言模型雏形N-Gram 和 文本表示BoW词袋 来实现文本情绪分类
  • 数据结构 -- 树形查找(三)红黑树
  • Flink 作业提交流程
  • 墨水屏显示模拟器程序解读
  • 《信息论与编码》课程笔记——信源编码(2)
  • vue3_flask实现mysql数据库对比功能
  • FreeSWITCH 简单图形化界面43 - 使用百度的unimrcp搞个智能话务台,用的在线的ASR和TTS
  • NAT(网络地址转换)逻辑图解+实验详解
  • 抖音视频怎么去掉抖音号水印
  • tomcat查看状态页及调优信息
  • 碎片笔记|PromptStealer复现要点(附Docker简单实用教程)
  • oracle 资源管理器的使用
  • C# String 格式说明符
  • python创建flask项目
  • 动态内存管理2+柔性数组
  • 5.18 day24
  • RabbitMq C++客户端的使用
  • QT聊天项目DAY11
  • 服务端HttpServletRequest、HttpServletResponse、HttpSession
  • 软件工具:批量图片区域识别+重命名文件的方法,发票识别和区域选择方法参考,基于阿里云实现
  • SuperYOLO:多模态遥感图像中的超分辨率辅助目标检测之论文阅读
  • 05 部署Nginx反向代理
  • Flink Table SQL
  • [SpringBoot]Spring MVC(4.0)
  • TASK03【Datawhale 组队学习】搭建向量知识库
  • 【图像处理基石】OpenCV中都有哪些图像增强的工具?
  • 护网行动——蓝队防守方案指南
  • AI写PPT可以用吗?我测试了3款AI写PPT工具,分享感受
  • Vue 3.0 中的slot及使用场景