把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉。 輸入一個非減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。 NOTE:給出的全部元素都大於0,若數組大小爲0,請返回0。數組
這是一道二分查找的變形題,這裏的旋轉數組是兩個有序的遞增子數組拼接起來的,且前面一個子數組裏的任意一個數都大於後面子數組中的數。而要找的最小值就是先後兩個子數組的分界點。spa
用三個指針begin、end、middle分別指向數組的首尾和中間元素指針
1)若middle元素大於或者等於begin元素說明中間元素位於前半部分數組中,最小元素在後半部分的數組中,則將begin設爲middle繼續在後半部分中尋找code
2)若middle元素小於或者等於end元素說明中間元素位於後半部分數組中,最小部分在前半部分或者中間元素就是最小元素,則將end設爲middle繼續在前半部分中尋找blog
這樣不斷縮小範圍,直到最後begin和end會成爲相鄰的元素,此時end所指元素就是最小值排序
特殊狀況:class
1)0個元素旋轉到後半部分,那麼此時旋轉數組就是一個非遞減數組,最小值就是第一個元素,也就是爲何初始middle設爲0的緣由遍歷
2)當begin、end、middle三個元素都相等時,沒法判斷中間元素在前半部分數組仍是後半部分數組,只能遍歷數組尋找最小值di
例如1,1,1,0,1和1,0,1,1,1均可以當作是0,1,1,1,1的翻轉數組while
1 public int minNumberInRotateArray(int [] array) { 2 if(array.length==0) 3 return 0; 4 int begin = 0,end = array.length-1,middle = 0; 5 while(array[begin]>=array[end]){ 6 if((end-begin)==1){ 7 middle = end; 8 break; 9 } 10 middle = (begin+end)/2; 11 if(array[begin]==array[middle]&&array[middle]==array[end]){ 12 return minInOrder(array,begin,end); 13 } 14 if(array[middle]>=array[begin]){ 15 begin = middle; 16 }else if(array[middle]<=array[end]){ 17 end = middle; 18 } 19 20 } 21 return array[middle]; 22 } 23 24 private int minInOrder(int[] array,int begin,int end){ 25 int min = array[begin]; 26 for(int i = begin+1;i<end;i++){ 27 if(min>array[i]){ 28 min = array[i]; 29 } 30 } 31 return min; 32 }