33. Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

受教于 StefanPochmann 的帖子:
https://discuss.leetcode.com/topic/34491/clever-idea-making-it-simple,文中有特别nice的解释,如下:

Explanation(下面自己附加了一点中文解释)

Let's say nums looks like this: [12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Because it's not fully sorted, we can't do normal binary search. But here comes the trick:

  • If target is let's say 14, then we adjust nums to this, where "inf" means infinity:
    [12, 13, 14, 15, 16, 17, 18, 19, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf, inf]

  • If target is let's say 7, then we adjust nums to this:
    [-inf, -inf, -inf, -inf, -inf, -inf, -inf, -inf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

And then we can simply do ordinary binary search.

Of course we don't actually adjust the whole array but instead adjust only on the fly only the elements we look at. And the adjustment is done by comparing both the target and the actual element against nums[0].

核心思想强调 mid 若和 target 在同一侧,num = A[mid],否则,若 target 在左侧,mid 一定就在右侧,num 将被赋值为 inf, 否则自然被赋值为 inf. 经过 inf, -inf 的这种设计后,binary search与传统教科书上的一模一样.

感动到流泪额,真心佩服这些超级聪明并懂得分享的人.

依据人家思想,自己的 implementation:
(O(logn)) time, (O(1)) extra space.

int search(vector<int>& A, int ta) {
	int lo = 0, hi = A.size() - 1;

	while (lo <= hi) {
		int mid = lo + ((hi - lo) >> 1);
		// mid 若和 target 在同一侧,num = A[mid]
		// 否则,若 target 在左侧,mid 一定就在右侧,num 将被赋值为 inf
		// 否则自然被赋值为 inf.
		double num = (A[mid] < A[0]) == (ta < A[0]) ? A[mid] :
						ta < A[0] ? -INFINITY : INFINITY;

		if (num > ta)
			hi = mid - 1;
		else if (num < ta)
			lo = mid + 1;
		else
			return mid;
	}
	return -1;
}
原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7399521.html