题目描述:
题目中最重要的两点信息:
- nums为无重复元素的升序数组。
- 使用时间复杂度为O(log n)的算法。
从题目可以得知这又是一道二分法的题目, 基本思路比较简单, 需要注意的是一些边界情况。 代码如下:
function searchInsert(nums: number[], target: number): number {
if(nums.length === 0) return 0;
//定义左右双指针
let left = 0;
let right = nums.length - 1;
/*
重点: 这里和以往不同, 采用的是 left < right, 而不是 left <= right
*/
while (left < right) {
const mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
//因为数组无重复元素, 所以相等的情况直接返回索引
return mid;
}
if (nums[mid] < target) {
//中间值小于目标值的情况, 继续从数组左半部分开始寻找
left = mid + 1;
} else if (nums[mid] > target) {
//中间值大于目标值的情况, 继续从数组右半部分开始寻找
right = mid - 1;
}
}
/*
这里是数组中没有找到 target 的情况
如果当前 左侧指针值大于 target, 则返回 left
为什么要加等于呢? 等于情况不是while中能遇到么?
当数组长度小于2时, 是不会进入while循环的..最开始便漏掉了这个边界情况
*/
if (nums[left] >= target) return left;
/**
如果当前 左侧指针值小于 target, 则返回 left + 1
*/
return left + 1;
}
递归版本(需要调整方法参数):
function searchInsert(nums: number[], target: number, start: number = 0, end: number = nums.length - 1): number {
if(nums.length === 0) return 0;
if (end - start < 1) {
if (nums[start] >= target) {
return start;
}
return start + 1;
}
const mid = Math.floor((start + end) / 2);
if (nums[mid] === target) return mid;
return nums[mid] > target
? searchInsert(nums, target, start, mid - 1)
: searchInsert(nums, target, mid + 1, end);
}