题目:
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例一:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例二:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
思路
在一个有序的数组中进行搜索,第一反应是二分法,但本题是要找元素的第一个和最后一个位置,那一次二分是不够的。总的思路是,先进行一次二分查找,找到元素的其中一个位置,在分别对这个位置的两边进行二分,确定左边界,和右边界。(找右边界的话在取mid值的地方,我是取上边界的)。
代码:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
if(nums.length == 0){
return [-1,-1];
}
let len = nums.length;
const find = (low, high)=>{
while(low<=high){
let mid = low+((high-low)>>1);
if(nums[mid] == target){
return mid;
}
if(nums[mid]>target){
high =mid-1;
}else{
low = mid+1;
}
}
return -1;
}
// 找左边界
const findleft = (low,high)=>{
while(low<high){
let mid = low+((high-low)>>1);
if(nums[mid] == target){
high = mid;
}else{
low = mid+1;
}
}
return high;
}
//找右边界
const findright = (low,high)=>{
while(low<high){
let mid = low+((high-low+1)>>1);
if(nums[mid] == target){
low = mid;
}else{
high = mid-1;
}
}
return low;
}
let temp = find(0,len-1);
if(temp == -1){
return [-1,-1];
}
return [findleft(0,temp), findright(temp,len-1)];
};