1. 程式人生 > >【劍指Offer】面試題8:旋轉陣列的最小數字

【劍指Offer】面試題8:旋轉陣列的最小數字

一:題目描述

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

二:解題思路

非遞減排列  :數字按照增加的順序排列,其中有相等的數
 如:

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,.:非遞增排列

題目中把排序陣列的前面n個元素搬到最後面,可能n=0,要注意

第一個簡單的想法:

旋轉後的陣列實際上可以劃分為兩個排序陣列,而且前面的子陣列的元素都大於等於後面子陣列的元素,而最小元素剛好是這兩個子陣列的分界線

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
                if(rotateArray.size()==0)
            return 0;
        if(rotateArray.size()==1)
            return rotateArray[0];
        
        int length=rotateArray.size();
        int i;
        for(i=0;i<=length-2;i++)
            if(rotateArray[i]>rotateArray[i+1])
                return rotateArray[i+1];
        //如果陣列轉換後,是一個非遞減排序,第一位是最小的
        return rotateArray[0];
    }
};

時不要把題看的太簡單,往往都是出題者的坑,套路,就算實現了,可能也不是最佳情況,劍指Offer給出的最佳結果是基於排序的思想

用兩個指標分別指向兩個子陣列,第一個指標總是指向前面遞增陣列的元素,第二個指標總是指向後面遞增的陣列的元素,最終第一個指標指向前面子陣列的最後一個元素,第二個指標指向後面陣列的第一個元素,他們最終指向兩個相鄰的元素,而第二個指標剛好指向最小的元素。

特殊情況

當第一個指標,中間位置,與第二個指標所指元素相同的時候怎麼辦呢?採用順序查詢

三:程式碼實現

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0)
            return 0;
        if(rotateArray.size()==1)
            return rotateArray[0];
        
        int index1=0;
        int index2=rotateArray.size()-1;
        int midIndex=index1;
        
        while(rotateArray[index1]>=rotateArray[index2]){
            if(index2-index1==1){
                midIndex=index2;
                return rotateArray[midIndex];
            }
            
            midIndex=(index1+index2)/2;
            
            //三者相等
            if(rotateArray[index1]==rotateArray[midIndex] && rotateArray[midIndex]==rotateArray[index2])
                return MinInOrder(rotateArray,index1,index2);
            if(rotateArray[index1]<=rotateArray[midIndex])
                index1=midIndex;
            else if(rotateArray[index2]>=rotateArray[midIndex])
                index2=midIndex;

        }
        return rotateArray[midIndex];
    }
    
    int MinInOrder(vector<int> rotateArray,int index1,int index2){
        int result=rotateArray[index1];
        int i=index1+1;
        for(i;i<=index2;i++)
            if(result>rotateArray[i])
                result=rotateArray[i];
        return result;
    }
};