Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm‘s runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].
For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].
思路:
1)先用二分查找找到点,然后再左右扩展,找到范围。如果有m个要搜寻点,算法复杂度为O(lgN+m),m<=N。最好的情况下是O(lgN),只有一个点的时候;最差情况O(N),全是要搜寻点的时候。这种做法可以Ac。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> result(2,-1);
int left = 0;
int right = nums.size()-1;
int mid = 0;
int first = -1;
int second = -1;
while(left<=right){
mid = left+(right-left)/2;
if(nums[mid] > target)
right = mid - 1;
if(nums[mid] < target)
left = mid + 1;
if(nums[mid] == target){
first = mid;
second = mid;
break;
}
}
for(int i=mid-1;i>=0;i--){
if(nums[i]==target)
first--;
else break;
}
for(int i=mid+1;i<nums.size();++i){
if(nums[i]==target)
second++;
else break;
}
result[0] = first;
result[1] = second;
return result;
}
};找左边界点时,修改二分查找的规则,如果找到点,还要继续往左二分直到找到左边界点;
找右边界点时,同理。
特别注意break的处理,当明显找不到点时break掉循环,对于找左边界点就是nums[right]<target。
这种解法复杂度是O(lgN)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int hit = -1;
int left=0, right=nums.size() - 1;
int first = 0, second = 0;
vector<int> ret(2, -1);
while(left <= right)
{
int mid = left + (right - left) / 2;
if(nums[right] < target) break;
if(nums[mid] >= target)
{
if(nums[mid] == target) hit = mid;
right = mid - 1;
}
else
{
left = mid + 1;
}
}
if(hit == -1) return ret;
first = hit;
left = hit;
right = nums.size() - 1;
hit = -1;
while(left <= right)
{
int mid = left + (right - left) / 2;
if(nums[left] > target) break;
if(nums[mid] <= target)
{
if(nums[mid] == target) hit = mid;
left = mid + 1;
}
else
{
right = mid - 1;
}
}
if(hit == -1) return ret;
second = hit;
ret[0] = first;
ret[1] = second;
return ret;
}
};
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/ciaoliang/article/details/46754043