1. 程式人生 > >劍指offer第六題【旋轉陣列的最小數字】c++實現

劍指offer第六題【旋轉陣列的最小數字】c++實現

題目描述

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

本題給的也算是有序數列,一看就應該和二分沾邊,事實也是這樣。

題目給的是非遞減序列,就是說有可能會有重複的數字,要注意一下。

來簡單分析一下陣列的可能。

旋轉過、沒旋轉過、所有元素都相等。

看題目吧旋轉過的陣列分成兩半,{3,4,5,} {1,2}。

可以看出如果旋轉過前面的陣列所有元素一定大於後面的所有元素。

如果沒旋轉過的話,首元素一定比尾元素要小。

如果中間元素大於尾元素,最小值一定在後半段。

如果中間元素小於首元素,最小值一定在前半段。

查到最後一定是剩兩個元素,後面的就是最小值,如果前面的是最小值就是沒旋轉的情況。

int minNumberInRotateArray(vector<int> rotateArray) {
    //其實不應該有空,因為是在牛客網做的題,有一組測試資料是空
    if(rotateArray.empty()){
        return 0;
    }
    int left=0;
    int right=rotateArray.size()-1;
    if(rotateArray[left]<rotateArray[right]){
        return rotateArray[left];
    }
    while(right>left){
        int mid=(right+left)/2;
        int middle=rotateArray[mid];
        int leftNumber=rotateArray[left];
        int rightNumber=rotateArray[right];
        if((right-left)==1){
            return rightNumber;
        }
        //左中右的值全都相等,不能確定在前還是在後,只能遍歷查後一個比前一個小就是最小值
        if(middle==leftNumber&&middle==rightNumber){
            for(int i=left;i<right;i++){
                if(rotateArray[i]>rotateArray[i+1]){
                    return rotateArray[i+1];
                }
            }
            //全相等的話直接返回最左值就行了
            return leftNumber;
        }else if(middle<leftNumber){
            right=mid;
        }else if(middle>rightNumber){
            left=mid;
        }
    }
}