35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 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
思路:
check条件: 首先我们的check
条件应该是找到第一个大于等于target
的位置即check if (nums[mid] >= target)
更新: 更新时, if (nums[mid] >= target)
我们可以判断结果位置应该在mid
左边而且包含mid
如: r = mid
模板: 因此我们套用第一套模板(mid = l + r >> 1
不用加1
的那套)
边界: 注意此题需要考虑特殊情况即当所有数都比target
小的情况,此时退出的情况是l=r=nums.size()-1
,明显我们的结果应该在边界+1
的位置,因此当结果为nums.size()-1
时需要特判一下,代码如下:
Java代码
class Solution {
public int searchInsert(int[] nums, int target) {
if(nums == null || nums.length == 0) return 0;
int l = 0,r = nums.length - 1;
//找到第一个大于等于target的位置
while(l < r){
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
//当所有数都比target小的情况,此时退出的情况是l=r=nums.size()-1,
//此时明显我们的结果应该在边界+1的位置,因此当结果为nums.size()-1时需要特判一下
if(l == nums.length - 1 && target > nums[l]) l++;
return l;
}
}
Go代码
func searchInsert(nums []int, target int) int {
// 由题意知:就是找大于等于target的最小值,符合二分模板的寻找绿色区域右边界的场景
// https://blog.youkuaiyun.com/YouMing_Li/article/details/113182720
if len(nums) == 0 {
return 0
}
l,r := 0,len(nums) - 1
for l < r {
mid := ( l + r) / 2
if (nums[mid] >= target) {
r = mid
} else {
l = mid + 1
}
}
//当所有数都比target小的情况,此时退出的情况是l=r=len(nums)
//此时明显我们的结果应该在边界+1的位置,因此当结果为len(nums]时需要特判一下
if l == len(nums) -1 && target > nums[l] {
return len(nums)
}
return l
}
上述代码完全也可以转换思路,变为寻找小于等于目标值的最大位置,只是后续的特判需要改一下,因为找不到目标值时,小于等于目标值的最大位置的下一位置才是插入位置
func searchInsert(nums []int, target int) int {
if len(nums) == 0 {
return 0
}
l,r := 0,len(nums) - 1
for l < r {
mid := ( l + r + 1) / 2
if (nums[mid] <= target) {
l = mid
} else {
r = mid - 1
}
}
//当所有数都比target大的情况,此时退出的情况是l=r=0,或者找到了目标值
if (l == 0 && nums[l] > target) || nums[l] == target {
return l
}
return l + 1
}```