劍指offer-面試題8 旋轉數組的最小數字

面試題8 旋轉數組的最小數字

  題目描述:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲 1。

思路

題目本身不難理解,就是一個有序數組的變形,這裏有兩個問題需要考慮:
  (1)題目中說的旋轉是一次旋轉還是不限次數?
  (2)數組中的數是嚴格遞增還是可以有相同的數出現?

思考

  我們先看第一個問題:如果能不限次數的話,那按照題目給的旋轉方式,完全可以將數組旋轉成一個無序數組,那尋找最小值只能是先排序再找最小值了,和題意不符,得出結論:只能旋轉一次;
  第二個問題:嚴格遞增是我們想要的,如果是嚴格遞增,那麼二分查找將會非常有用,能有效減小時間複雜度。
  考慮元素可以相同,極端情況:有個長度很大的數組,除了第一位是0之外,數組中其餘的數都是1。我們發現,如果對數組進行隨意旋轉操作,那麼0可能在的位置是數組的第2到n位。不能通過判斷大小(因爲只有一個元素不相同)來判斷,那隻能遍歷數組比較大小獲得最小值了。這嚴格來說也不太符合題意。但是在許多其它的答案中都考慮到了這個可能,仁者見仁,那我們也實現它。

代碼

package swordOffer;
/**
 * 這是劍指offer的第8題:旋轉數組的最小數字
 * 題目描述:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的
 * 旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如數
 * 組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲 1。
 * 
 * @author Stephen Huge
 *
 */
public class Ex08MinAtRotateArr {
    public static void main(String[] args) {
        Ex08MinAtRotateArr mara = new Ex08MinAtRotateArr();
        int[] arr = {2, 3, 4, 5, 1};
//      int[] arr = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1};
        int sol = mara.MinAtRotateArr(arr);
        System.out.println(sol);
    }
    public int MinAtRotateArr(int[] arr) {
        return  MinAtRotateArr(arr, 0, arr.length - 1);
    }
    private int MinAtRotateArr(int[] arr, int left, int right) {            
        int pivot = (left + right) / 2;
        if(arr[left] == arr[right]) {
            return iterateGet(arr);
        }
        if(left == pivot) {
            return arr[left + 1];
        }
        if(arr[left] < arr[pivot]) {
            left = pivot;
            pivot = (pivot + right) / 2;
        }
        if(arr[left] > arr[pivot]) {
            right = pivot;
            pivot = (pivot - left) / 2;
        }
        return MinAtRotateArr(arr, left, right);

    }
    // 數組左右數相同時,無法使用二分法判斷,採用遍歷判斷
    private int iterateGet(int[] arr) {
        int result = arr[0];
        for(int i = 1; i < arr.length; i++) {
            if(arr[i] < result) {
                result = arr[i];
            }
        }
        return result;
    }
}

執行結果是:

1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章