给你一个按照非递减顺序排列的整数数组 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]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109
Method:
面对非递减顺序排列的有序数组,使用二分法解决这些问题,依次查找元素的左右边界。
Code:
class Solution{
public:
// 在排序数组中查找元素的第一个和最后一个位置
vector<int> searchRange(vector<int> &nums,int target){
// 记录排序数组的长度
int n=nums.size();
// 记录元素在排序数组中的第一个和最后一个位置
vector<int> result={n-1,0};
// 如果数组的长度小于1
// 返回{-1,-1}
if(n<1){
result[0]=-1;
result[1]=-1;
return result;
}
// 首先查找元素的第一个位置
// 左指针
int left=0;
// 右指针
int right=n-1;
// 在右指针指向左指针的左边之前,持续遍历
while(left<=right){
// 计算二分的中间位置
int middle=(left+right)/2;
// 如果中间位置的值等于目标值
if(nums[middle]==target){
// 则元素的第一个位置更新
result[0]=middle;
// 右指针指向中间位置的左边
// 以查找更往前的位置
right=middle-1;
}
// 如果中间位置的值大于目标位置
else if(nums[middle]>target){
// 右指针指向中间位置的左边
// 向左边查找更小的数
right=middle-1;
}
// 如果中间位置的值大于目标位置
else if(nums[middle]<target){
// 左指针指向中间位置的右边
// 向右边查找更大的数
left=middle+1;
}
}
// 其次查找元素的最后一个位置
// 重新初始化左右指针的值
left=0;
right=n-1;
// 在右指针指向左指针的左边之前,持续遍历
while(left<=right){
// 计算二分的中间位置
int middle=(left+right)/2;
// 如果中间位置的值等于目标值
if(nums[middle]==target){
// 则元素的最后一个位置更新
result[1]=middle;
// 左指针指向中间位置的右边
// 以查找更往后的位置
left=middle+1;
}
// 如果中间位置的值大于目标位置
else if(nums[middle]>target){
// 右指针指向中间位置的左边
// 向左边查找更小的数
right=middle-1;
}
// 如果中间位置的值小于目标位置
else if(nums[middle]<target){
// 左指针指向中间位置的右边
// 向左边查找更大的数
left=middle+1;
}
}
// 如果查找完毕后,第一个位置或最后一个位置不是目标数值(为默认值)
// 返回{-1,-1}
if(nums[result[0]]!=target||nums[result[1]]!=target){
result[0]=-1;
result[1]=-1;
return result;
}
else {
// 如果第一个位置和最后一个位置都是目标值
// 则意味着查找成功
return result;
}
}
};
Reference:
(LeetCode)在排序数组中查找元素的第一个和最后一个位置——二分法_简十三的博客-CSDN博客_在排序数组中查找元素的第一个和最后一个位置
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array