搜索插入位置(第一个≥target的位置)

LeetCode 35 题「搜索插入位置」是二分查找的经典入门变种题,其核心并非简单的 "找目标值",而是求有序数组中第一个大于等于 target 的位置(也称为二分查找的 "下界")。本文从题目分析、核心原理、代码实现到拓展延伸,帮你彻底掌握这一高频考点。

一、题目回顾

题目描述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。要求:时间复杂度必须为 O(logn)。

二、核心原理:二分查找 "下界" 的逻辑

1. 为什么用二分查找?

题目要求时间复杂度 O(logn),而有序数组的二分查找恰好满足这一要求(顺序查找为 O(n),不符合要求)。

2. 二分 "下界" 的核心逻辑

我们维护一个闭区间 [left, right],通过不断缩小区间找到目标位置:

  • 初始化:left = 0,right = nums.size() - 1(覆盖整个数组);
  • 循环条件:left <= right(闭区间有效时继续查找);
  • 缩小区间规则:
    • 若 nums[mid] == target:直接返回 mid(找到目标值,其位置就是下界);
    • 若 target > nums[mid]:说明下界在右半区间,更新 left = mid + 1;
    • 若 target < nums[mid]:说明下界在左半区间,更新 right = mid - 1;
  • 循环终止:当 left > right 时,left 恰好是第一个≥target 的位置(下界)。

3. 关键:为什么循环结束返回 left?

循环终止时 left > right,此时:

  • right 是最后一个小于 target 的位置;
  • left 是第一个大于等于 target 的位置;这是二分查找求下界的 "固定结论",无需额外计算,直接返回 left 即可

三、完整代码实现

迭代版(工程首选)

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        
        // 闭区间 [left, right] 二分查找
        while (left <= right) {
            // 计算mid:避免 (left+right)/2 整数溢出
            int mid = left + (right - left) / 2;
            
            if (nums[mid] == target) {
                return mid; // 找到目标值,直接返回
            } else if (target > nums[mid]) {
                left = mid + 1; // 下界在右半区间
            } else {
                right = mid - 1; // 下界在左半区间
            }
        }
        // 循环结束,left 是第一个≥target的位置
        return left;
    }
};

递归版(理解逻辑用)

递归版更直观体现 "分治思想",核心逻辑与迭代版一致:

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        return binarySearch(nums, target, 0, nums.size() - 1);
    }

private:
    int binarySearch(vector<int>& nums, int target, int left, int right) {
        // 递归终止条件:返回下界 left
        if (left > right) return left;
        
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (target > nums[mid]) {
            // 递归查找右半区间
            return binarySearch(nums, target, mid + 1, right);
        } else {
            // 递归查找左半区间
            return binarySearch(nums, target, left, mid - 1);
        }
    }
};
相关推荐
一只不想敲代码的程序猿3 分钟前
如何更高效地拆解问题?
算法
微尘hjx1 小时前
【Deep-OC-SORT 02】多轨迹算法Deep-OC-SORT-相对 OC-SORT 的改进点
人工智能·算法·yolo·目标跟踪·视觉检测·ultralytics·deep-oc-sort
梦帮科技1 小时前
意识启发式量子隧穿退火算法用于全局优化 (CITA) 完整技术指南
网络·人工智能·算法·量子计算·模拟退火算法
一去不复返的通信er2 小时前
排序 + 双指针:力扣15三数之和
算法·leetcode
Pniubi3 小时前
力扣3无重复字符的最长字串(滑动窗口)
算法·leetcode·职场和发展
On The Road :3 小时前
深入理解 JVM 垃圾回收:GC 是什么、如何判定垃圾、四大回收算法全解析
jvm·算法
微尘hjx4 小时前
【Deep-OC-SORT 03】多轨迹算法Deep-OC-SORT-卡尔曼滤波预测过程
算法·yolo·目标跟踪·ultralytics·车跟踪·轨迹算法·deep-oc-sort
老师我太想进步了20266 小时前
【数据结构-3】算法美学之降复杂度
数据结构·算法
机器人零零壹11 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
ZhengEnCi14 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法