1. 程式人生 > >跟我一起學算法系列9---旋轉陣列的最小數字

跟我一起學算法系列9---旋轉陣列的最小數字

1.題目描述

把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1。

前提條件:給出的所有元素都大於0,若陣列大小為0,請返回0。

2.演算法分析

非減排序陣列旋轉之後的陣列,實際上可以劃分成兩個有序的子陣列,前面子陣列的元素大小都大於後面子陣列中的元素,因此我們可以使用二分查詢的思路解題。

(1)首先我們考慮沒有重複數字的情況

1)我們用兩個指標low和high分別指向陣列的第一個元素和最後一個元素。
2)找到陣列的中間元素。

中間元素大於第一個元素,則中間元素位於前面的遞增子陣列,此時最小元素位於中間元素的後面,移動指標low,指向中間元素。

中間元素小於第一個元素,則中間元素位於後面的遞增子陣列,此時最小元素位於中間元素的前面。移動指標high,指向中間元素。

3)迴圈執行,low指標總是指向前面遞增陣列的元素,high指標總是指向後面遞增的陣列元素。

當low指標指向前面陣列的最後一個元素,high指標指向後面陣列中的第一個元素。直到他們指向彼此相鄰的元素,此時high指標指向的就是最小的元素。

(2)有重複元素的情況
題目描述的是非減陣列,比如{1,0,1,1,1} 和 {1,1, 1,0,1} 可以是{0,1,1,1,1}的旋轉陣列。
中間元素1可以是後面的字陣列,也可以是前面的字陣列,所以也要特殊考慮。

3.程式碼例項

public class Solution {
    public int minNumberInRotateArray(int [] array) {
        int low = 0 ; int high = array.length - 1;   
        while(low < high){
            int mid = low + (high - low) / 2;        
            if(array[mid] > array[high]){
                low = mid + 1;
            }else if(array[mid] == array[high]){
                high = high - 1;
            }else{
                high = mid;
            }   
        }
        return array[low];
    }
}