旋轉數組的最小數字


把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉
輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素
例如數組 [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];
    }
}
相關文章
相關標籤/搜索