劍指offer--旋轉陣列的最小值
阿新 • • 發佈:2018-12-14
題目如下
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{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]; } }