Given an array of integers sorted in ascending order, 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].
题意就是找 target = 8 的索引开始和结束的地方,如上列,就是[3, 4], 找不到 target 的话 return [-1, 1].
网上大神用各种二分做实现,什么两次二分,往左侧二分,右侧二分的.本人智商不够,实在无法理解.
下面的想法也用二分,运行时间不比那些难懂的实现差,且非常易理解,比较亲民, 就像星爷在电影"功夫"里的台词:"终于有个长的像人的!".
拿上列来说,想法超级简单,就是用二分找到8(既 A[mid] == target 的情况),我们不管哪个8(可能有多个8), 找到就好.然后向左,右,分别利用循环判断边界,就这么简单,这才像人思考的样子额^^.
人家想法,咱家代码:
(O(logn)) time, (O(1)) extra space.
vector<int> searchRange(vector<int>& A, int ta) {
const int n = A.size();
vector<int> res(2, -1);
int lo = 0, hi = n - 1;
while (lo <= hi) {
int mid = lo + ((hi - lo) >> 1);
if (A[mid] > ta) hi = mid - 1;
else if (A[mid] < ta) lo = mid + 1;
else { //A[mid] == ta, 然后往分别向左右扫,找边界
res[0] = res[1] = mid;
int j = mid - 1;
while (j >= 0 && A[j] == ta) { // left scan
res[0] = j;
j--;
}
j = mid + 1;
while (j < n && A[j] == ta) { // right scan
res[1] = j;
j++;
}
return res; // 这不加 return, 则超时
}
}
return res;
}