LeetCode 35.搜索插入位置

LeetCode 35.搜索插入位置

1、题目

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

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

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

示例 1:

markdown 复制代码
输入: nums = [1,3,5,6], target = 5
输出: 2

示例 2:

markdown 复制代码
输入: nums = [1,3,5,6], target = 2
输出: 1

示例 3:

markdown 复制代码
输入: nums = [1,3,5,6], target = 7
输出: 4

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 为 无重复元素 的 升序 排列数组
  • -104 <= target <= 104

2、思路

题目要求我们找到 目标值 在 有序数组中 会被 顺序插入的位置,其实插入的位置无非是以下四种情况。

  • 目标值在数组所有元素之前
  • 目标值等于数组中某一个元素
  • 目标值插入数组中的位置
  • 目标值在数组所有元素之后

根据题目可知,数组是有序的,在 有序数组 中查找符合条件的某个数(或者它的下标),这是二分查找的基本条件。同时题目又强调数组中 无重复元素,这样使用二分查找返回的元素下标就是唯一的。所以这道题可以使用二分查找来求解。

3、二分法(左闭右闭区间)

代码:

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int n = nums.size();
        int left = 0;
        int right = n - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当 left == right,区间 [left, right]依然有效
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle;
            }
        }
        // 分别处理如下四种情况
        // 目标值在数组所有元素之前  [0, -1]
        // 目标值等于数组中某一个元素  return middle;
        // 目标值插入数组中的位置 [left, right],return  right + 1
        // 目标值在数组所有元素之后的情况 [left, right], 因为是右闭区间,所以 return right + 1
        
        return right + 1;
        // return left;
    }
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

4、二分法(左闭右开区间)

代码:

cpp 复制代码
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,[left, right)

        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间
            int middle = left + ((right - left) >> 1);

            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在 [middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值的情况,直接返回下标
            }
        }
        // 分别处理如下四种情况
        // 目标值在数组所有元素之前 [0,0)
        // 目标值等于数组中某一个元素 return middle
        // 目标值插入数组中的位置 [left, right) ,return right 即可
        // 目标值在数组所有元素之后的情况 [left, right),因为是右开区间,所以 return right
        return right;
        // return left
    }
};

复杂度分析

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)
相关推荐
沙蒿同学2 小时前
不引 Ghostscript:我用纯 Go 给 PDF 做了一场「压缩手术」
前端·后端·github
春弦_3 小时前
自用算法整理二
数据结构·算法·图论
背调合规知识库3 小时前
数据授权中处理目的、方式与信息种类核验什么?方法、证据与误区
职场和发展
hetao17338374 小时前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
前进的李工4 小时前
飞书企业知识库设计+后端高频八股
数据库·redis·后端·mysql·性能优化·飞书·rag
java_nnnn4 小时前
LeetCode刷题滑动窗口(串联所有单词的子串+最小覆盖的子串)Java
算法·leetcode·职场和发展
SailingCoder5 小时前
【封闭结束1】端到端交付:Agent 一次请求如何走完全链路
前端·安全·ai·面试·agent·harness
王老师青少年编程5 小时前
2025年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
Navigator_Z5 小时前
LeetCode //C - 1301. Number of Paths with Max Score
c语言·算法·leetcode
Interview Aid1126 小时前
Uber Interview Process 完整指南:面试流程、OA 真题与 VO 备考
面试·职场和发展