4.22 35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
分析
在一个排序数组中查找一个数值的索引,使用二分查找是最直观的思路;
难点在于如何在目标数不存在的情况下返回应该插入的位置.
1、暴力查找,只需要找到第一个大于等于target的数字位置,返回其索引,
时间复杂度O(n)
2、二分查找:
①target存在,返回索引
②target不存在,返回left
var searchInsert = function (nums, target) {
// 二分查找
var left = 0;
var right = nums.length - 1;
while (left <= right) {// 注意一
var middle = Math.floor(left + (right - left) / 2)//注意二
if (nums[middle] == target) {
return middle;
}
else if (nums[middle] < target) {
left = middle + 1//注意三
}
else if (nums[middle] > target) {
right = middle - 1
}
}
return left //注意四
};
注意一:
while循环判断,while(left <= right)的终止条件是 left == right + 1,这时候 while 循环终止是正确的,直接返回 -1 即可。
while(left < right)的终止条件是 left == right,middle = left = right,已经跳出while循环,漏掉了结果。
注意二:
如果用mid=(left+right)/2,在运行二分查找程序时可能溢出超时,因为如果left和right相加超过表示的最大范围时就会溢出变为负数。
所以如果想避免溢出,应该使用mid=Math.floor(left+(right-left)/2)。
注意三:
因为nus[middle]已经判断过了,所以right = middle-1
注意四:
如果查找一个不存在的数字,最后跳出while循环的条件是left = right+1;·表示没找到目标数字,target位于nums[right]和nums[left] = nums[right+1]中间,所以返回left,表示应该插入数字的索引