Spurs

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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;
}
posted on 2017-08-22 19:05  英雄与侠义的化身  阅读(112)  评论(0编辑  收藏  举报