34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
思路
- 俗话说二分法思路简单,细节是魔鬼。以寻找开始位置为例,范围为[0, n - 1],首先寻找到nums[mid] == target值后,不能立刻返回,需要将right缩小为mid - 1,当nums[mid] > target时,right = mid - 1,当nums[mid] < target时,left = mid + 1。
- 当退出循环时,left只有两种情况,left == n表示数组没寻找到target所以left一直递增,left不等于n,此时right必定小于left,需要判断nums[left]是否等于target。
- 同理寻找最右思路类似,只需判断right即可。
代码
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int n = nums.size();
if(n == 0) {
return {-1, -1};
}
int left = 0, right = n - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if(nums[mid] == target) {
right = mid - 1;
}
else if(nums[mid] > target) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
vector<int> ans(2, -1);
if(left == n || nums[left] != target) {
ans[0] = -1;
}
else {
ans[0] = left;
}
left = 0, right = n - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if(nums[mid] == target) {
left = mid + 1;
}
else if(nums[mid] > target) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
if(right == -1 || nums[right] != target) {
ans[1] = -1;
}
else {
ans[1] = right;
}
return ans;
}
};