给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]
。
示例 1:
输入: nums = [5,7,7,8,8,10]
, target = 8
输出: [3,4]
注意时间复杂度时logn
这个题和33题很像,都规定时间复杂度是Logn,所以应该想到是二分法
很多解法是用二分法找到目标,然后再用遍历的方法确定边界,这个方法时错误的,会超出时间限制。因为可能target有很多个,那么时间复杂度就不是Logn了。
正确的做法是不断的进行二分查找,找到每一个目标的位置,将每次找到的target的位置记录下来(实际上是与最小值和最大值进行比较)。
1.二分查找到第一个目标
2.如果找到了,则将位置与之前找到的位置进行比较。继续对(lbegin, mid-1)和(mid+1,end)进行二分查找。
注意这里是直接(lbegin, mid-1)和(mid+1,end)二分查找,应该是会有重复的查找
对first和last的初始化也要注意是什么
class Solution {
public:
void bin_search(vector<int>& nums, int begin, int end, int target, int &a, int &b)//a代表第一个位置,b代表最后一个位置
{
if(begin > end)
return;
int mid = (begin + end) / 2;
if(nums[mid] == target) {
if(mid < a)
a = mid;
if(mid > b)
b = mid;
bin_search(nums, begin, mid - 1, target, a, b);
bin_search(nums, mid + 1, end, target, a, b);
}
else if(nums[mid] < target)
bin_search(nums, mid + 1, end, target, a, b);
else
bin_search(nums, begin, mid - 1, target, a, b);
}
vector<int> searchRange(vector<int>& nums, int target)
{
int a = nums.size(), b = -1;
bin_search(nums, 0, nums.size() - 1, target, a, b);
if(a != nums.size() && b != -1)
return vector<int>{a, b};
return vector<int>{-1, -1};
}
};