题目
🔗题目链接: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
思路
要在数组中插入目标值,无非是这四种情况。
- 目标值在数组所有元素之前
- 目标值等于数组中某一个元素元素
- 目标值插入数组中的位置
- 目标值在数组所有元素之后
这四种情况确认清楚,我们就可以开始解题了。
💡注意:题目中存在 排序数组、数组中无重复元素 条件,我们都可以想一想是否可以使用 二分法。
代码
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;
}