本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
题目解析
思路一
我们先定义一个函数findMid,作用是传入左右边界,用二分法找到数组中目标值的下标; 先整体执行一次,找到目标值的第一个位置,标记为mid。如果没找到,则说明没有,返回[-1,-1] 然后从这个mid一分为二,[0,mid-1]/[mid+1, nums.length-1],分别对两边执行findMid,判断结果是否为-1,如果还不是-1,说明继续找到,则目标结果左边界拓宽到新的mid。右边同理。 直到两边都找到边界,返回结果。
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
let leftPointer = 0
let rightPointer = nums.length - 1
function findMid(left, right){
while (left <= right){
let mid = Math.floor( (left + right) / 2 )
if ( nums[mid] > target ){
right = mid - 1
} else if ( nums[mid] < target ){
left = mid + 1
} else {
return mid
}
}
return -1
}
let mid = findMid(leftPointer, rightPointer)
let midLeft = mid
let midRight = mid
while ( findMid(leftPointer, midLeft - 1) !== -1 ){
midLeft = findMid(leftPointer, midLeft - 1)
}
while ( findMid(midRight + 1, rightPointer) !== -1 ){
midRight = findMid(midRight + 1, rightPointer)
}
return [midLeft,midRight]
};
思路二
使用indexOf求出第一个index值,使用lastIndexOf()求出最后一个index值,分别进行插入数组中即可。
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
var str = []
if(nums.length===0){return [-1,-1]}
str.push(nums.indexOf(target))
str.push(nums.lastIndexOf(target))
if(str){
return str;
}
return [-1,-1]
};
思路三
我们首先获取到目标值中的所有索引,在把他全部存储到一个数组中,在取出数组中的,第一个索引和最后一个索引,这样就可以获取到起始位置和终点位置
var searchRange = function(nums, target) {
var ponitList=[];
var tempList=[];
for (var i in nums){
if(nums[i]==target){
ponitList.push(i);
}
}
if(ponitList.length==0){
tempList=[-1,-1];
}else{
tempList=[ponitList[0],ponitList[ponitList.length-1]]
}
return tempList
};