把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素
例如數組 [3,4,5,1,2] 爲 [1,2,3,4,5] 的一個旋轉,該數組的最小值爲 1
給出的全部元素都大於 0,若數組大小爲 0,請返回 0java
對於這道題,首先要知道非遞減排序是什麼意思,說實話我之前是真沒接觸過這個詞面試
形同 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... 爲非遞增排列數組
這樣子雖然能夠達成目標,但顯然不是面試官想看到的code
旋轉以後的數組實際上能夠劃分紅兩個有序的子數組:前面子數組的大小都大於後面子數組中的元素排序
注意到實際上最小的元素就是兩個子數組的分界線。本題目給出的數組必定程度上是排序的,所以咱們試着用二分查找法尋找這個最小的元素io
須要考慮三種狀況:class
array[mid] > array[high]while
出現這種狀況的 array 相似 [3,4,5,6,0,1,2],此時最小數字必定在 mid 的右邊co
low = mid + 1block
array[mid] < array[high]
出現這種狀況的 array 相似 [2,2,3,4,5,6,6],此時最小數字必定就是 array[mid] 或者在 mid 的左邊。由於右邊必然都是遞增的
high = mid
array[mid] == array[high]
出現這種狀況的 array 相似 [1,0,1,1,1] 或者[1,1,1,0,1],此時最小數字很差判斷在 mid 左邊仍是右邊,只好一個一個試
high = high - 1
public class Solution { public int minNumberInRotateArray(int [] array) { int low = 0; int high = array.length - 1; int mid = (low + high) / 2; while(low < high) { // 此時最小數字必定在 mid 的右邊 if(array[mid] > array[high]) { low = mid + 1; // 此時最小數字必定就是 array[mid] 或者在 mid 的左邊 } else if(array[mid] < array[high]) { high = mid; // 不能判斷在 mid 左邊仍是右邊,這時只好一個一個試 } else { high--; } mid = (low + high) / 2; } return array[low]; } }