[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,1,4,3] 或 [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);
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);
}
}