【劍指Offer】面試題8:旋轉陣列的最小數字
阿新 • • 發佈:2019-01-06
一:題目描述
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非遞減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。
二:解題思路
非遞減排列 :數字按照增加的順序排列,其中有相等的數
如:
1,2,3,4,5,.:遞增排列
9,8,7,6,5.:遞減排列
1,2,3,3,4,5,8,8,.:非遞減排列
9,8,7,7,6,5,5,2,1,.:非遞增排列
題目中把排序陣列的前面n個元素搬到最後面,可能n=0,要注意
第一個簡單的想法:
旋轉後的陣列實際上可以劃分為兩個排序陣列,而且前面的子陣列的元素都大於等於後面子陣列的元素,而最小元素剛好是這兩個子陣列的分界線
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size()==0) return 0; if(rotateArray.size()==1) return rotateArray[0]; int length=rotateArray.size(); int i; for(i=0;i<=length-2;i++) if(rotateArray[i]>rotateArray[i+1]) return rotateArray[i+1]; //如果陣列轉換後,是一個非遞減排序,第一位是最小的 return rotateArray[0]; } };
有時不要把題看的太簡單,往往都是出題者的坑,套路,就算實現了,可能也不是最佳情況,劍指Offer給出的最佳結果是基於排序的思想
用兩個指標分別指向兩個子陣列,第一個指標總是指向前面遞增陣列的元素,第二個指標總是指向後面遞增的陣列的元素,最終第一個指標指向前面子陣列的最後一個元素,第二個指標指向後面陣列的第一個元素,他們最終指向兩個相鄰的元素,而第二個指標剛好指向最小的元素。
特殊情況
當第一個指標,中間位置,與第二個指標所指元素相同的時候怎麼辦呢?採用順序查詢
三:程式碼實現
class Solution { public: int minNumberInRotateArray(vector<int> rotateArray) { if(rotateArray.size()==0) return 0; if(rotateArray.size()==1) return rotateArray[0]; int index1=0; int index2=rotateArray.size()-1; int midIndex=index1; while(rotateArray[index1]>=rotateArray[index2]){ if(index2-index1==1){ midIndex=index2; return rotateArray[midIndex]; } midIndex=(index1+index2)/2; //三者相等 if(rotateArray[index1]==rotateArray[midIndex] && rotateArray[midIndex]==rotateArray[index2]) return MinInOrder(rotateArray,index1,index2); if(rotateArray[index1]<=rotateArray[midIndex]) index1=midIndex; else if(rotateArray[index2]>=rotateArray[midIndex]) index2=midIndex; } return rotateArray[midIndex]; } int MinInOrder(vector<int> rotateArray,int index1,int index2){ int result=rotateArray[index1]; int i=index1+1; for(i;i<=index2;i++) if(result>rotateArray[i]) result=rotateArray[i]; return result; } };