34. 在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
题目
示例 1
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3
输入:nums = [], target = 0
输出:[-1,-1]
答案
对撞指针
类似快速排序
时间复杂度为:logn
思路:
声明对撞指针
left/right
声明中位数 mid
根据二分法比较
target
,找到对应下标 mid- while 循环条件:
while (left <= right) {}
nums[mid]
比较target
- 找到对应下标
break
- 未找到
left = mid +1 / right = mid -1
- while 循环条件:
不存在:
if(left > right) return [-1, -1]
根据 mid 分别向两遍查找相同值的下标
let i = mid
let j = mid
//向左尝试找相同的元素
while(nums[i] === nums[i - 1]) i--;
//向右尝试找相同的元素
while(nums[j] === nums[j + 1]) j++;返回
[i,j]
var searchRange = function(nums, target) {
let left = 0
let right = nums.length - 1
let mid // 找到目标
// 根据二分法不target
while (left <= right) {
mid = parseInt((left + right) / 2);
if (nums[mid] === target) break;
if (nums[mid] > target) {
right = mid - 1
}else{
left = mid + 1;
}
}
if(left > right) return [-1, -1];
let i = mid
let j = mid
//向左尝试找相同的元素
while(nums[i] === nums[i - 1]) i--;
//向右尝试找相同的元素
while(nums[j] === nums[j + 1]) j++;
return [i, j];
};
var nums = [5,7,7,8,8,10], target = 8
console.log(searchRange(nums,target))
暴力
var searchRange = function(nums, target) {
// 下标数组
let result = []
nums.forEach((item,index)=>{
if(item === target){
// 最大长度为2
if(result.length === 2){
result.pop()//把末尾弹出
result.push(index)//更新
}else{
result.push(index)
}
}
})
// 判断结果长度
if(result.length > 1){ // 直接返回
return result
}else if(result.length === 1){ // 仅一个
result = [result[0],result[0]]
return result
}else{ // 没找到
return [-1,-1]
}
};
var nums = [5,7,7,8,8,10], target = 8
console.log(searchRange(nums,target))