在排序数组中查找元素的第一个和最后一个位置
题目
:
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题
示例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]
JS
思路
根据题目了解到,目的查找target并要求时间复杂度为O(logn),那么第一时间想到二分法
如果有重复就输出对应的最小值下标和最大值下标
二分法的left , right加以加工利用就可以作为对应重复元素的左边界和右边界
分三种情况:
第一种:target不在数组中,返回[-1,-1] (都找不到边界)
第二种:target在数组中,但不存在该元素返回[-1,-1]
第三种:target在数组中,存在该元素返回[leftBorder + 1, rightBorder - 1]
代码
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
var leftBorder = searchLeftBorder(nums , target)
var rightBorder = searchRightBorder(nums , target)
if(leftBorder === -2 || rightBorder === -2){
return [-1,-1]
}else if(rightBorder - leftBorder === 1){ //情况二:在数组中但不存在
return [-1,-1]
}else { //第三中就是存在
return [leftBorder+1 , rightBorder-1]
}
};
var searchRightBorder = function (nums , target) {
let left = 0
let right = nums.length - 1
var rightBorder = -2
while(left <= right){
let mid = Math.floor((left + right) / 2)
if(target < nums[mid]){
right = mid - 1
}else{
left = mid + 1
rightBorder = left
}
}
return rightBorder
}
var searchLeftBorder = function (nums , target) {
let left = 0
let right = nums.length - 1
var leftBorder = -2
while(left <= right){
let mid = Math.floor((left + right) / 2)
if(target <= nums[mid]){
right = mid - 1
leftBorder = right
}else{
left = mid + 1
}
}
return leftBorder
}