刷題筆記(十八)——旋轉數組的最小數字
題目描述
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。
例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。
NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
思路
(1)最容易想到的思路,就是從前向後遍歷數組,若遇到前一個數大於後一個數時,則這後一個數則爲最小的數
有數相等的情況:如1、1、2、2、2進行旋轉,(2、1、1、2、2), (1、2、2、2、1)
特殊情況爲該數組中的數全部相等1、1、1,則旋轉完的數組和原數組是相同的
(2)當數組較長時,上面的方法開銷較大
採用二分的思想
設置left,right和mid指針,當left<right時,說明該數組沒有進行旋轉。則left指向就爲最小
當left>=right時
當left>mid時說明mid在後面這個旋轉過去的非遞減序列中且最小數在mid和left之間(包括mid),right取到mid的值
當left<=mid時,說明mid在前面這個非遞減序列中且最小數在mid和right之間,left取到mid
直到left+1=right,則right爲最小
特殊情況爲思路1中提到的有相同元素時,left、right、mid三值相等時,可在該範圍用思路一遍歷。
代碼
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0)
return 0;
/*for(int i=1;i<rotateArray.size();i++)
{
if(rotateArray[i]>rotateArray[i-1])
i++;
else
return rotateArray[i];
}
return rotateArray[0];*/
int left=0,right=rotateArray.size()-1;
if(rotateArray[left]<rotateArray[right])
return rotateArray[left];
int mid=0;
while(rotateArray[left]>=rotateArray[right])
{
if(right - left == 1){
mid = right;
break;
}//if
mid = left + (right - left) / 2;
if(rotateArray[left] == rotateArray[right] && rotateArray[left] == rotateArray[mid]){
return MinOrder(rotateArray,left,right);
}//if
// mid = (right + left) / 2;
if(rotateArray[mid]>=rotateArray[left])
left=mid;
else
right=mid;
}
return rotateArray[mid];
}
private:
// 順序尋找最小值
int MinOrder(vector<int> &num,int left,int right){
int result = num[left];
for(int i = left + 1;i < right;++i){
if(num[i] < result){
result = num[i];
}//if
}//for
return result;
}
};