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.