力扣HOT100刷题记录-二分-题解-35.搜索插入位置

5 阅读2分钟

搜索插入位置(Search Insert Position)

题目描述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

要求:

  • 请必须使用时间复杂度为 O(log n) 的算法。

示例:

输入: nums = [1,3,5,6], target = 5

输出: 2

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

输出: 1

输入: nums = [1,3,5,6], target = 7

输出: 4

解题思路分析

方法一:二分查找法(推荐)

由于数组已排序且要求时间复杂度为 O(log n),二分查找是最佳选择。

时间复杂度:O(log n)

空间复杂度:O(1)

#include<iostream>
#include<vector>

using namespace std;

int searchInsert(vector<int>& nums, int target) {
    // 左闭右闭区间
    int left = 0, right = nums.size() - 1;
    
    while(left <= right){  // [left, right] 为合法区间
        int mid = left + (right - left) / 2;  // 防止溢出
        
        if(nums[mid] == target){
            return mid;      // 找到目标,直接返回索引
        }else if(nums[mid] > target){
            right = mid - 1; // 目标在左半区间
        }else if(nums[mid] < target){
            left = mid + 1;  // 目标在右半区间
        }
    }
    
    // 如果未找到,返回插入位置(即left指针位置)
    return left;
}

int main(){
    vector<int> nums = {1,3,5,6};
    int target = 5;
    cout << searchInsert(nums, target) << endl;
    return 0;
}

核心思想与关键问题解答

1. 为什么使用二分查找?

思考过程:

  • 数组已排序,这是二分查找的前提条件
  • 题目要求 O(log n) 时间复杂度,二分查找正好满足
  • 即使目标不存在,也需要找到插入位置,二分查找的终止条件能自然提供这个位置

2. 为什么返回 left 指针?

关键原因:

  • 当循环结束时,left > right,此时:

    • left指向第一个大于等于 target 的元素位置
    • right指向最后一个小于 target 的元素位置
  • 插入位置应该是第一个大于等于 target 的位置,即 left

示例验证:

  • nums = [1,3,5,6], target = 2

    • 最终 left=1, right=0,返回1(正确插入位置)
  • nums = [1,3,5,6], target = 7

    • 最终 left=4, right=3,返回4(正确插入位置)

算法流程详解

模拟执行过程(nums = [1,3,5,6], target = 2)

步骤leftrightmidnums[mid]操作说明
初始03---初始化
103133>2 → right=0目标在左边
200011<2 → left=1目标在右边
结束10--返回left=1插入位置为1

最终输出:1