LeetCode35 搜索插入位置
题目
需要验证的情况:
解题
解题一:二分法版本一
官方的代码是每次都会记录 target <= nums[mid] 的 mid 下标:
// javascript
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0, right = n - 1, ans = n;
while (left <= right) {
const mid = left + ((right - left) >> 1);
if (nums[mid] >= target) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
};
其实可以直接返回 left,有两种情况:
- target 在 nums 里,left = right 时, mid = left, nums[mid] = target, right = mid - 1,但是 left 没有变,仍然指向 target;
- target 不在 nums 里,left = right 时, mid = left
- 如果 nums[mid] > target, nums[mid] 是第一个大于 target 的数,right = mid - 1,left = mid 是 target 应该插入的位置
- 如果 nums[mid] < target, nums[mid] 是最后一个小于 target 的数,left = mid + 1,即 target 应该插入的位置
// javascript
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0, right = n - 1;
while (left <= right) {
const mid = left + ((right - left) >> 1);
if (nums[mid] >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
};
解题二:二分法版本二
注意 right 的初始值是 n,因为出循环时 left = right,所以返回 left 和 right 都可以。
// javascript
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0;
// 定义target在左闭右开的 [left, right) 区间里
let right = n;
// left = right 时, [left, right) 是无效的空间
while (left < right) {
const mid = left + ((right - left) >> 1);
if (nums[mid] >= target) {
// 下一个区间 [left, mid)
right = mid;
} else {
// 下一个区间 [mid + 1, right)
left = mid + 1;
}
}
return right;
};