題目:把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。面試
解題思路:
一、暴力解法,從頭至尾遍歷一次,咱們就能找出最小的元素,複雜度爲O(n),可是沒有利用輸入的旋轉數組的特性,確定達不到面試官的要求。
二、二分查找,這裏的數組能夠當作兩個有序的子數組,二分查找對有序數組很是有效,複雜度爲O(logn)。數組
具體分析:
一、先分析數組的特色,這兩個有序的數組,前一個數組的全部值都大於等於後一個數組的值,最小值應該出如今後一個數組的第一個元素上。
二、二分查找縮小查找範圍依賴於中間值和待查找值的比較。 設置兩個指針,index1指向第一個元素,index2指向最後一個元素。 若是中間indexMid指向的元素大於或者等於index1指向的元素,那麼,最小的元素必定在indexMid以後。若是indexMid指向的元素小於或者等於index2指向的元素,那麼最小元素必定在indexMid以前或者就是indexMid所指向的元素。 就是利用這種判斷條件來不斷縮小查找範圍。
三、結束條件:
最終index1會指向前一個子數組的最後一個元素,index2會指向後一個子數組的第一個元素,二者之間的距離爲1。而index2指向的就是最小的元素。
四、特殊狀況:
若是被旋轉的個數爲0,也就是隻有一個升序的數組,這時候沒有必要去查找,由於第一個元素就是最小的元素。
還有在查找中常常遇到的一種狀況,就是有相同元素的狀況。 好比 {1, 0, 1, 1, 1} 是{0, 1, 1, 1, 1}的一個旋轉。index一、index二、indexMid指向的元素值都爲1,這時候不能判斷最小值所在的範圍,因此須要只能順序遍歷。spa
代碼以下:指針
public class Solution { public static Integer min(int[] array){ if (array == null || array.length == 0) { return null; } int low=0; int high=array.length-1; int mid=low;//若是這自己就是一個遞增數組 //若是進入這個循環說明是旋轉數組 while(array[low]>=array[high]){ if(high-low==1){ mid=high; break; } mid=(low+high)/2; //若是high,low,mid指向同一個元素,則該數組中右重複的數字,則只能順序查找 if (array[mid] >= array[low]) { low = mid; } else if (array[mid] <= array[high]) { high = mid; } } return array[mid]; } //順序查找 public static int minInOrder(int[] array) { int min = array[0]; for (int i = 1; i < array.length; i++) { if (array[i] < min) { min = array[i]; } } return min; } public static void main(String[] args) { int[] array = {3,4,5,1,2}; Integer result = min(array); System.out.println(result); } }