劍指offer第六題【旋轉陣列的最小數字】c++實現
阿新 • • 發佈:2019-01-07
題目描述
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入一個非遞減序列的一個旋轉,輸出旋轉陣列的最小元素。例如陣列{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; } } }