给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n)
级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
C++1
解题思路:
首先判断数组的大小,如果为空,直接返回{-1,-1}
;
采用二分查找的第三个模板,先找到数组中的任意一个下标上的数字等于target
的情况,然后根据这个下标向左和向右遍历,找到连续的这几个target
数字的边缘下标。存进vector
中返回。如果找不到,直接return {-1,-1};
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> res;
if (nums.size() == 0)
return {-1,-1};
int begin = 0, mid=0, end = nums.size()-1, temp=-9; //temp是一个暂时的下标,初始值自己设置为-9
while(begin+1<end){
mid = begin+(end - begin) / 2;
if(nums[mid] == target){
temp = mid; // 找到一个符合的下标就退出循环
break;
}else if(nums[mid] < target){
begin = mid;
}else{
end = mid;
}
}
// 如果上述步骤找到一个下标等于target,那么向左向右分别遍历找到边缘下标
if(temp != -9 || nums[begin] == target || nums[end] == target){
// 这两个是当begin+1=end时候while退出,所以要在这判断一下,以免疏漏
if(nums[begin] == target) temp = begin;
if(nums[end] == target) temp = end;
// 向左遍历
int l = temp;
while(l>=0){
if(l == 0 && nums[l] == target){
res.push_back(l);
break;
}
if(l != 0 && nums[l] == target){
l--;
}else{
res.push_back(++l);
break;
}
}
// 向右遍历
int r = temp;
while(r<=nums.size()-1){
if(r == nums.size()-1 && nums[r] == target){
res.push_back(r);
break;
}
if(r != nums.size()-1 && nums[r] == target){
r++;
}else{
res.push_back(--r);
break;
}
}
return res;
}else{
return {-1,-1};
}
}
};