Search for a Range
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]
.
这道题目要求O(log n)的复杂度,那肯定用二分查找。一开始想到的是先二分查找,然后再左右扩展。代码如下:
class Solution
{
public:
vector<int> searchRange(int A[], int n, int target)
{
vector<int> result;
if(n<=0)
{
result.push_back(-1);
result.push_back(-1);
return result;
}
int low = 0;
int high = n-1;
int mid;
while(low <= high)
{
mid = (low+high)/2;
if(A[mid]==target)
break;
else if(A[mid] >= target)
high = mid - 1;
else
low = mid + 1;
}
if(A[mid] != target)
{
result.push_back(-1);
result.push_back(-1);
return result;
}
else
{
low = high = mid;
while(low >= 1)
{
low -- ;
if(A[low]!=target)
{
low ++;
break;
}
}
while(high <= n-2)
{
high ++ ;
if(A[high]!=target)
{
high --;
break;
}
}
result.push_back(low);
result.push_back(high);
return result;
}
}
};
这样Accept没问题,时间是74ms,但是这个扩展复杂度很难讲,万一一个数组全是target,那么扩展复杂度是O(n),这肯定是不合适的。
为此呢,我想到的是以第一查找到的下标为轴,然后将轴的两边分别查找target,直到返回结果是-1或者到达边界才退出。
代码如下:
class Solution
{
public:
int BinarySearch(int A[],int low, int high, int target)
{
int mid;
while(low<=high)
{
mid = (low+high)/2;
if(A[mid]==target)
return mid;
else if(A[mid]>target)
high = mid-1;
else
low = mid+1;
}
return -1;
}
vector<int> searchRange(int A[], int n, int target)
{
vector<int> result(2,-1);
if(n<=0)
return result;
int pos;
int temp;
int start,end;
pos = BinarySearch(A, 0, n-1, target);
if(pos == -1)
return result;
else
start = end = pos;
temp = pos;
while(temp >= 0)
{
temp = BinarySearch(A,0,temp-1,target);
if(temp == -1)
break;
else
start = temp;
}
temp = pos;
while(temp < n)
{
temp = BinarySearch(A,temp+1, n-1, target);
if(temp == -1)
break;
else
end = temp;
}
result[0] = start;
result[1] = end;
return result;
}
};
时间是52ms.