題目描述 旋轉(zhuǎn)數(shù)組的最小數(shù)字
把一個(gè)數(shù)組最開始的若干個(gè)元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。 輸入一個(gè)非減排序的數(shù)組的一個(gè)旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。 例如數(shù)組{3,4,5,1,2}為{1,2,3,4,5}的一個(gè)旋轉(zhuǎn),該數(shù)組的最小值為1。 NOTE:給出的所有元素都大于0,若數(shù)組大小為0,請(qǐng)返回0。
解題思路
轉(zhuǎn)自 https://blog.csdn.net/htt789/article/details/80970533
輸入的數(shù)組為非減排序數(shù)組的旋轉(zhuǎn),數(shù)組分為兩個(gè)排好序的數(shù)組。{3,4,5,1,2}其中前半部分{3,4,5}和后半部分{1,2}都為非減數(shù)組,且前半部分的數(shù)大于等于后半部分。
對(duì)于排序的數(shù)組->二分查找
1.取數(shù)組中間數(shù),若中間的數(shù)大于數(shù)組第一個(gè)數(shù),說明中間數(shù)位于前半個(gè)非遞減數(shù)組中,因此最小值在數(shù)組的后半部分,3 4 5 6 0 1 2。
2.若中間數(shù)小于數(shù)組最后一個(gè)數(shù),說明中間數(shù)位于后半個(gè)非遞減數(shù)組中,因此最小值在數(shù)組的前半部分, 4 5 1 2 3。
3.若數(shù)組起始數(shù),中間數(shù),末位數(shù)相同,則不能判斷最小值位于數(shù)組的前半部分還是后半部分,需要采用暴力排序,依次比較查找。(特殊輸入:重復(fù)數(shù)字的數(shù)組) 1 1 1 0 1
4.直到指向數(shù)組前和后的指針下標(biāo)相鄰時(shí),后面的指針對(duì)應(yīng)數(shù)組的最小數(shù)字。
測(cè)試用例:
- 邊界值測(cè)試:輸入直接為非遞減數(shù)組(未經(jīng)過旋轉(zhuǎn)),如果第一個(gè)數(shù)字小于最后一個(gè)數(shù)字,說明數(shù)組遞增,可以直接返回第一個(gè)數(shù)字作為最小數(shù)字。
- 輸入數(shù)組含有重復(fù)的數(shù)字
代碼
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.empty()) return 0;
int left = 0, right = rotateArray.size() - 1;
while (left < right) {
//確認(rèn)子數(shù)組是否是類似1,1,2,4,5,..,7的非遞減數(shù)組
if (rotateArray[left] < rotateArray[right]) return rotateArray[left];
int mid = left + (right - left) / 2;
//如果左半數(shù)組為有序數(shù)組
if (rotateArray[left] < rotateArray[mid])
left = mid + 1;
//如果右半數(shù)組為有序數(shù)組
else if (rotateArray[mid] < rotateArray[right])
right = mid;
//否則,rotateArray[left] == rotateArray[mid] == rotateArray[right]
else {
++left;
}
}
return rotateArray[left];
}
};