[LeetCode] Find Minimum in Rotated Sorted Array

Suppose a sorted array 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).

Find the minimum element.

You may assume no duplicate exists in the array.

这题事实上就是找翻转后右側部分的最左端点。典型的二分搜索变体,大致思路分成两种情况讨论:

1)假设搜索范围在翻转部分,略微复杂一点:

1.1)假设中间点在翻转后的左側,则应该往右寻找。由于假设没有冗余元素。最小值不可能出如今左側;

1.2)假设中间点在翻转后的右側。则应该往左寻找。只是这时应该缓存下当前中间点相应的元素,由于再往左的话,可能就到了翻转后的左側部分。就可能错过全局最小值了。

2)假设搜索范围在排序的部分。则当前的最小值肯定是在最左端。

只是这个时候最左端的值不一定是全局最小。须要跟缓存的最小值在进行一次比較。

	public int findMin(int[] num) {
		int low = 0, high = num.length - 1;
		int ret = Integer.MAX_VALUE;

		while (low <= high) {
			int mid = low + (high - low) / 2;
			// On the sorted part.
			if (num[low] <= num[high]) {
				return Math.min(num[low], ret);
			} else { // On the rotated part.
				// num[mid] is on the left rotated part.
				if (num[mid] >= num[low]) {
					low = mid + 1;
				} else { // num[mid] is on the right rotated part.
					ret = num[mid];
					high = mid - 1;
				}
			}
		}
 	return ret;
	}

注意最后的return语句事实上是不可能到达的。由于一旦low和high相等,那么num[low]和num[high]也必定相等了,直接就返回了。

Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Suppose a sorted array 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).

Find the minimum element.

The array may contain duplicates.

假设存在冗余元素,那么则必须把num[low]和num[high]相等的情况单独讨论了。这样的情况下。仅仅能老老实实的线性搜索了。假设使用二分查找,这个时候可能会出问题:假设输入数组的最左和最右元素相等,并且都存在一片连续相等的区域,那么中间点可能也会在最左或者最右的连续相等区域中。这个时候应该是无法推断再往哪个方向搜索的。比如[3, 3, 3, 3, 3, 3, 4, 2, 3, 3]和[3, 3, 4, 2, 3, 3, 3, 3, 3, 3],取中间点后根本无法推断继续往哪个方向搜索。

	public int findMin(int[] num) {
		int low = 0, high = num.length - 1;
		int ret = Integer.MAX_VALUE;

		while (low <= high) {
			// Linear scan to find a non-flat part.
			if (num[low] == num[high]) {
				ret = Math.min(num[low], ret);
				low++;
				continue;
			}
			int mid = low + (high - low) / 2;
			// On the sorted part.
			if (num[low] < num[high]) {
				return Math.min(num[low], ret);
			} else { // On the rotated part.
				// num[mid] is on the left rotated part.
				if (num[mid] >= num[low]) {
					low = mid + 1;
				} else { // num[mid] is on the right rotated part.
					ret = num[mid];
					high = mid - 1;
				}
			}
		}
		return ret;
	}

相比于之前不考虑冗余元素的解法,就是多了一个if语句,单独处理num[low]和num[high]相等的情况。

posted on 2017-06-29 16:44  yjbjingcha  阅读(156)  评论(0编辑  收藏  举报

导航