旋轉陣列的最小值
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。 NOTE:給出的所有元素都大於0,若陣列大小為0,請返回0。
分析:首先將陣列的情況分為兩種: 1.最小值在中間值的右邊; 2.最小值在中間值的左邊; (begin,end,mid是陣列下標,min是陣列中的最小值) 6 7 8 9 10 11 1 2(begin=0 end=7 mid=3 min=1) 6 7 1 2 3 4 5 5 (begin=0 end=7 mid=3 min=1)
思路一:(二分查詢)
每次用中間下標mid
對應的陣列值rotateArray[mid]
和結尾下標end
對應的陣列值rotateArray[end]
比較,如果rotateArray[mid] >rotateArray[end]
,就說明最小值在[mid+1,end]
範圍中,否則最小值在[begin,mid]
範圍中,最後的結束條件是begin和end相等。
示例輸入:6501 6828 6963 7036 7422 7674 8146 8468 8704 8717 9170 9359 9719 9895 9896 9913 9962 154 293 334 492 1323 1479 1539 1727 1870 1943 2383 2392 2996 3282 3812 3903 4465 4605 4665 4772 4828 5142 5437 5448 5668 5706 5725 6300 6335 示例輸出:154
int minNumberInRotateArray(vector<int> rotateArray) { //使用二分查詢 int begin = 0; int end = rotateArray.size()-1; int mid = ((end-begin)>>1)+begin; while(begin < end) { if(rotateArray[mid] < rotateArray[end]) end = mid; else begin = mid+1; mid = ((end-begin)>>1)+begin;//更新中間下標 } return rotateArray[begin]; }
思路二:找有序陣列的下標分界點 這種方法適用於陣列個數少的情況,如果陣列長度很大或者陣列整體有序,則會很時間複雜度近乎暴力求解。 分析:通過陣列的旋轉,陣列會有兩種形式,即{3,4,5,1,2}為{1,2,3,4,5},整體有序或者是兩個各自有序的陣列,只要找到兩個陣列的分界點就是此問題的解,如果遍歷到陣列尾部還沒有找到分界點,說明陣列整體有序,則需返回首元素。上程式碼:
int minNumberInRotateArray(vector<int> rotateArray) {
int i ;
for(i = 0;i<rotateArray.size()-1;i++)
if(rotateArray[i] > rotateArray[i+1])
return rotateArray[i+1];
return rotateArray[0];
}