转载请注明出处:http://write.blog.csdn.net/postedit/52738221
原题: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].
解答:
C++版本
vector<int> searchRange(int A[], int n, int target) {
int i = 0, j = n - 1;
vector<int> ret(2, -1);
// Search for the left one
while (i < j)
{
int mid = (i + j) /2;
if (A[mid] < target) i = mid + 1;
else j = mid;
}
if (A[i]!=target) return ret;
else ret[0] = i;
// Search for the right one
j = n-1; // We don't have to set i to 0 the second time.
while (i < j)
{
int mid = (i + j) /2 + 1; // Make mid biased to the right
if (A[mid] > target) j = mid - 1;
else i = mid; // So that this won't make the search range stuck.
}
ret[1] = j;
return ret;
}
思路:
这道题的难点是给定的序列带有重复数字,查找特定元素所在的范围,而一般的二分查找适合查找非重复元素的情况,所以需要改进算法。
如:
target = 5
1 2 4 5 5 5 5 7 8 9 10 12
应该返[3, 6]
1--查找左侧5时,需要满足的条件是当中间值A[mid]>=target时,右侧索引j = mid
一旦A[mid] = 5,mid右侧(包括5)的元素都放弃,但是mid本身保留下来。
下面分两种情况:
1)这个5是最左侧的5,例如:
2 2 2 5
那么这个最左侧的5将一直保留
2)这个5不是最左侧的5,例如:
3 3 3 3 5 5
中间的5会被继续探测到,一旦第二次出现A[mid] = 5,右边的5都被抛弃。这样
继续下去,又分为情况1、2,循环下去,直到找到最左侧的5
2--查找右侧5时,需要满足的条件是当中间值A[mid] = target时,左侧索引 i = mid