
题目分析
- 最简单的方法是遍历数组记录target第一次出现的下标和最后一次出现的下标,但是这种方法的时间复杂度为O(n)。
- 因为数组是非递减数组,所以我们可以通过二分法查找第一个大于等于target的位置和最后一个小于等于target的位置,这样时间复杂度就降到了O(logn)
代码
let search = function (nums, target) {
if (target < nums[0] || target > nums[nums.length - 1]) {
return 0;
}
const search = (bool) => {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
const mid = left + ((right - left) >> 1);
if (nums[mid] < target || (!bool && nums[mid] === target)) {
left = mid + 1;
} else if (nums[mid] > target || (bool && nums[mid] === target)) {
right = mid - 1;
}
}
return bool ? left : right;
};
const startIndex = search(true);
const endIndex = search(false);
if (nums[startIndex] !== target || nums[endIndex] !== target) {
return 0;
}
return endIndex - startIndex + 1;
};