題目描述
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。 輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。 NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
解題思路
旋轉數組可以分爲兩個有序的數組,最小元素就是這兩個數組的分界點。可以用二分查找來解決:
- 當數組大小爲0時,返回0;
- 用istart,istop,imid分別指向第一個元素、最後一個元素和中間元素:
- 若中間元素比第一個元素和最後一個元素都大,則說明最小值在右側,此時讓istart指向中間元素的下一個元素;
- 否則,若中間元素小於最後一個元素且第一個元素大於最後一個元素(確保旋轉),說明最小值在左側,此時讓istop指向中間元素;
- 否則,數組不是遞增的,存在相同元素,比如{1,1,1,0,1},則遍歷數組,找到最小值。
代碼
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if (rotateArray.size() == 0)
return 0;
int istart = 0, istop = rotateArray.size() - 1;
while (istart < istop){
if (istart + 1 == istop)
return min(rotateArray[istart], rotateArray[istop]);
int start = rotateArray[istart];
int stop = rotateArray[istop];
int imid = istart + ((istop - istart) >> 1);
int mid = rotateArray[imid];
if (start < mid && mid > stop){
istart = imid + 1;
}
else if (start > stop && mid < stop){
istop = imid;
}
else{
int mymin = INT_MAX;
for (int j = istart; j != istop + 1; j++){
mymin = min(mymin, rotateArray[j]);
}
return mymin;
}
}
return rotateArray[istart];
}
};