
本题为二分法的一个题型,在有序数组里查找一个数,简称为「二分下标」。
思路:先考虑特例,空数组,直接返回。然后分别对第一个位置和最后一个位置进行查找。也就是运用两次二分查找法。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size() == 0) return {-1, -1};
//给定目标值在数组中的开始位置
int left = 0;
int right = nums.size() - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] < target){ //小于目标值的一定不是开始位置
left = mid + 1; //目标值可能在[mid + 1, right]
} else right = mid;
}
int first = left;
if(nums[left] != target) return {-1, -1}; //没有目标值
//给定目标值在数组中的结束位置
left = 0;
right = nums.size() - 1;
while(left < right){
int mid = left + (right - left + 1) / 2;
if(nums[mid] > target){ //大于目标值的一定不是开始位置
right = mid - 1; //目标值可能在[left, mid - 1]
} else left = mid;
}
int end = left;
return {first, end};
}
};
把查找位置的部分封装为函数
class Solution {
public:
int findFirstPosition(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] < target){ //小于目标值的一定不是开始位置
left = mid + 1; //目标值可能在[mid + 1, right]
} else right = mid;
}
return left;
}
int findLastPosition(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left < right){
int mid = left + (right - left + 1) / 2;
if(nums[mid] > target){ //大于目标值的一定不是开始位置
right = mid - 1; //目标值可能在[left, mid - 1]
} else left = mid;
}
return left;
}
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size() == 0) return {-1, -1};
int first = findFirstPosition(nums, target);
if(nums[first] != target) return {-1, -1}; //没有目标值
int end = findLastPosition(nums, target);
return {first, end};
}
};