35.搜索插入位置

82 阅读2分钟

题目

🔗题目链接:35. 搜索插入位置 - 力扣(LeetCode)

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

你可以假设数组中无重复元素。

示例 1:

  • 输入: [1,3,5,6], 5
  • 输出: 2

示例 2:

  • 输入: [1,3,5,6], 2
  • 输出: 1

示例 3:

  • 输入: [1,3,5,6], 7
  • 输出: 4

示例 4:

  • 输入: [1,3,5,6], 0
  • 输出: 0

思路

要在数组中插入目标值,无非是这四种情况。

image.png

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

这四种情况确认清楚,我们就可以开始解题了。

💡注意:题目中存在 排序数组数组中无重复元素 条件,我们都可以想一想是否可以使用 二分法

代码

function searchInsert(nums: number[], target: number): number {
    const lens = nums.length;
    let left = 0;
    let right = lens - 1;
    
    while (left <= right) {
        // 防止溢出 等同于 Math.floor((left + right) / 2)
        let mid = Math.floor(left + (right - left) / 2);
        
        if (target < nums[mid]) {
            // target 在左区间,在 [left, mid - 1] 的区间中,right 应该往左移
            right = mid - 1;
        } else if (target > nums[mid]) {
            // target 在右区间,在 [mid + 1, right] 的区间中, left 应该往右移
            left = mid + 1;
        } else {
            // target === nums[mid]
            return mid;
        }
    }
    
    // 1. 目标值在数组所有元素之前。这种情况下,left 不动,right 会在 while 循环中变为 -1。所以需要返回 0,也就是 right + 1。
    // 2. 目标值等于数组中某一个元素元素。这种情况下返回 mid。
    // 3. 目标值插入数组中的位置。这种情况下,right会向左移,left会向右移,最终在 right < left 的时候停下。此时应该返回 right + 1 或者 left。
    // 4. 目标值在数组所有元素之后。这种情况下,right 不动,left 会在 while 循环中一直往右走,最后在 left > right && left === lens 的情况下退出循环。这是应该返回 right + 1 或者 left。
    // 综上四种情况,在这个位置返回 right + 1 最合适
    return right + 1;
}