題目如下
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。 輸入一個非減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。 NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。
解題思路:
有三種思路
- 很簡單了,遍歷數組取得最小值。
我最開始就是這種想法。。。太low了function minNumberInRotateArray(rotateArray) { if( rotateArray.length === 0 ){ return 0; }else{ let len = rotateArray.length; let min = rotateArray[0]; for(var i = 1 ; i < len ; i++){ if( rotateArray[i] < min ){ min = rotateArray[i]; } } return min; } }
- 對上面的方法進行部分優化,可以將數組看出兩個非遞減的數組,a[x1…xn] b[y1…yn]
顯然最小值就是y1,在a中x1到xn是非遞減的,所以遍歷時,找到第一個a[n] > a[n+1]的n即可,結果就是a[n+1]
同時對於[1,1,1,1]這種恆等的數組需要做特殊處理function minNumberInRotateArray2(rotateArray) { if( rotateArray.length === 0 ){ return 0; }else{ let len = rotateArray.length; for(var i = 1 ; i < ( len - 1 ) ; i++){ if( rotateArray[i] > rotateArray[ i + 1] ){ return rotateArray[i+1] } if( i === len - 1){ return rotateArray[i]; } } } }
- 這個是比較高級的一種方法了,就是利用二分法進行查找
同上面的方法,將數組arr看作兩個非遞減的數組a[x1…xn] , b[y1…yn]
3-1. 取left = 0, right =arr.length -1;
3-2. 取left和right的中間值 mid
3-3. 拿mid的對應的值與left對應的值進行比較
如果arr[mid] >= arr[left],說明mid位於a[x1…xn]中,最小值b[y1]位於mid和right中,設置left=mid
如果arr[mid] < arr[left],說明mid位於b[y1…yn]中,最小值b[y1]位於left和mid中,設置right=mid
3-4. 重複上述步驟3-2和3-3直到 right - left == 1
3-5. 結果arr[left] = a[xn], arr[right] = b[y1],最小值爲arr[right]function minNumberInRotateArray(rotateArray) { if( rotateArray.length === 0 ){ return 0; }if( rotateArray.length === 1){ return rotateArray[0]; }else{ let len = rotateArray.length; let left = 0; let right = len - 1; while( right - left !== 1 ){ let center = Math.floor( (left + right) / 2 ); if( rotateArray[center] >= rotateArray[left]){ left = center; }else{ right = center; } } return rotateArray[right]; } }