1. 程式人生 > >[LeetCode] Find Minimum in Rotated Sorted Array II (包含遞增和遞減旋轉,含有重複數字)

[LeetCode] Find Minimum in Rotated Sorted Array II (包含遞增和遞減旋轉,含有重複數字)

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

這個是接著上一篇的:http://blog.csdn.net/lgd_yyf/article/details/40536943

針對原題中有重複數字的情況,在上一篇遞迴解法的基礎之上,稍作修改即可。

注意到,我們在選擇下一次遞迴的位置時,可以發現,在無重複數字時,只有兩種情況:

1、num[mid] > Math.max(num[start], num[end])

2、num[mid] < Math.min(num[start], num[end])

但是包含重複數字時,情況就不一樣了,有可能出現num[mid]和其中一個相等的情況,故需要分類討論。在分類之前,對陣列做如下處理:若rotate的位置恰好出現重複數字當中,則將後面的重複數字去掉(這一點在後面分類的時候,將起到作用)。下面開始分類:(函式為 public int searchMin(int[] num, int start, int end) ;)

int mid=(start+end)/2;

1、num[mid] >= num[start] && num[mid] <= num[end]  示例:[ 4,3,1,1,1] 或 [3,4,1,1,1] 或 [1,1,1,1,1]

若都取等號,則說明陣列都是同一數字,無論何種遞迴,最後都會返回正確值;

若 num[mid] == num[start],則 num[mid] < num[end] ,根據上篇所講的取 最小值和最大值原理,

 return searchMin(num, mid, end);

同理,若 num[mid] == num[end],則 

 return searchMin(num, mid, end);

2、num[mid] <= num[start] && num[mid] >= num[end] 示例:[ 1,1,14,3] 或 [1,1,1,

3,4] 

若 num[mid] == num[start],則 num[mid] > num[end] ,根據上篇所講的取 最小值和最大值原理,

 return searchMin(num, mid, end);

同理,若 num[mid] == num[end],則 

 return searchMin(num, mid, end);

3、num[mid] >= num[start] && num[mid] >= num[end] 示例:[ 4,3,6,6,5] 或 [3,4,5,5,1] 

4、num[mid] <= num[start] && num[mid] <= num[end] 示例:[ 3,4,1,1,2] 或 [4,3,1,6,5] 

3、4情況就是和上一題中的原理一樣,這裡不再贅述。

事實上,在判斷的時候 用 if-else if-else對1、2、3、4順序判斷下來 ,3、4中的等號情況是不會出現的。

實現如下:

public int findMin(int[] num) {
	int len = num.length;
	// 去掉末尾和開頭重複的部分
	if (num[0] == num[len - 1]) {
	    while (len >= 2 && num[len - 2] == num[len - 1])
	         len--;
	    len--;
	}
	if (len <= 1) {
	    return num[0];
	}
	return searchMin(num, 0, len - 1);
}

public int searchMin(int[] num, int start, int end) {
	if (start + 1 == end) {
	    return Math.min(num[start], num[end]);
	}

	int mid = (start + end) / 2;
	if (num[mid] >= num[start] && num[mid] <= num[end]) {
	    if (num[mid] == num[start])
	        return searchMin(num, mid, end);
	    else
	        return searchMin(num, start, mid);
	} else if (num[mid] <= num[start] && num[mid] >= num[end]) {
	    if (num[mid] == num[end])
	        return searchMin(num, start, mid);
	    else
	        return searchMin(num, mid, end);
	} else if (num[mid] >= num[start] && num[mid] >= num[end]) {
	    if (num[start] > num[end])
	        return searchMin(num, mid, end);
	    else
	        return searchMin(num, start, mid);
	} else {
	    if (num[start] > num[end])
	        return searchMin(num, start, mid);
	    else
	        return searchMin(num, mid, end);
	}
}