题目大意
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
解题思路
题目要求时间复杂度为 O(log n) 级别,因此本题考虑二分法。该题可以拆分为两个子问题:(1)在一个有序数组中找到某个特定值的左边界;(2)在一个有序数组中找到某个特定值的右边界;
在一个有序数组中找到某个特定值的左边界
- 当中点位置大于target时,right向左移动;
- 当中点位置小于target时,left向右移动;
- 当中点位置等于target时,此时我们在寻找左边界,而且现在的中点位置的值等于target。若再将left向右移动,则至少会越过当前中点位置的target,因此无法找到左边界。此时,应该向左移动right。
int findLeft(vector<int> & nums, int target){
int left = 0, right = nums.size() - 1, mid = 0;
while (left <= right){
mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
}
return (left < nums.size() && nums[left] == target) ? left : -1;
}
在一个有序数组中找到某个特定值的右边界
分析思路同左边界,左右颠倒即可。
inf findRight(vector<int> & nums, int target){
int left = 0, right = nums.size() - 1, mid = 0;
while (left <= right){
mid = left + (right - left) / 2;
if (nums[mid] <= target)
left = mid + 1;
else
right = mid - 1;
}
return (right >= 0 && nums[right] == target) ? right : -1;
}
};