旋轉數組的最小值

題目:把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。 輸入一個非減排序的數組的一個旋轉,輸出旋轉數組的最小元素。 例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。  NOTE:給出的所有元素都大於0,若數組大小爲0,請返回0。

其實一開始做這道題我是拒絕的,因爲題目中直接一個求最小值的操作就可以通過的,所以,一直不想看具體怎麼簡化解答的。

最近得找實習了,不得不拿起了減脂offer(皮.jpg)這本書。又翻到了這一頁。仔細看了看裏面的講述,確實值得簡化。幫助我們去理解二分的操作。類似的還有一個問題就是求數組中的局部最小值,也可以通過這個二分的思想來解答。

題目中已經說得很清楚了,講一個非遞減的數組做了一個定義好的旋轉,所以,將數組分爲了兩部分,第一部分和第二部分都是非遞減的,兩部分交界處類似於一個斷崖。所以,最小值一般都是在懸崖底部,所以,可以通過二分的方法找到這個值。

這裏設置兩個指針,分別是left和right,開始的時候left指向第一部分的開頭,right指向第二部分的結尾。一般情況下,right指向的值是小於或等於left的。這時候我們的任務就是去找那個懸崖,一步一步肯定是有點慢了,這時候採用二分的思想。

確定好中間點之後,讓我們看一下mid指向的值在數組的第一部分還是第二部分,如果在第一部分即array[left]<=array[mid],如果在第二部分即array[mid]>=array[right].這時候,可以通過範圍的縮小來查找這個最小值的存在。

當然存在多個1,一個0的情況,這種情況比較奇葩,因爲整個數組就像平地一樣,那個最小值肯定是坑的存在。這時候,我們需要一點一點的找到這個坑了。就需要在指定的範圍內查找這個最小值。當然,這裏因爲array[left]==array[mid]==array[right],那隻能這樣找了。

/*

*/
public int minNumberInRotateArray(int [] array) {
    if (array==null||array.length==0) {
        return 0;
    }
    int left=0;
    int right=array.length-1;
    while (array[left]>=array[right]) {
        if(left-right==1){
            return array[right];
            break;
        }
        int mid=(left+right)/2;
        if (array[left]==array[mid]&&array[mid]==array[right]) {
            return findMin(array,left,mid);
        }
        if (array[mid]>=array[left]) {
            left=mid;
        }else if (array[mid]<=array[right]) {
            right=mid;
        }
    }
    return array[right];
}
public static int findMin(int[]array,int index1,int index2){
    int min=array[index1];
    for (int i=index1;i<index2;i++) {
        if (min>array[i]) {
            min=array[i];
        }
    }
    return min;
}

 

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