解題筆記(35) 旋轉陣列中的最小元素

2021-05-27 19:44:18 字數 1082 閱讀 3546

問題描述:把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個排好序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。

思路:這道題最直觀的解法並不難。從頭到尾遍歷陣列一次,就能找出最小的元素,

時間複雜度顯然是o(n)。但這個思路沒有利用輸入陣列的特性。既然有時間複雜度更小的演算法,我們容易想到二分查詢,因為它的時間複雜度為o(logn)。這個問題是否可以運用二分查詢呢?答案是肯定的。觀察一下陣列的特性,首先遞增(稱為遞增a),然後突然下降到最小值,然後再遞增(稱為遞增b)。當然還有一種特殊情況,就是陣列遞增,中間沒有下降,即旋轉元素個數為0。

對於一般的情況,假設a為輸入陣列,

left 和 right 為陣列左右邊界的座標,考察中間位置的值a[mid] ,

如果a[mid] <= a[right],表明處於遞增b,調整右邊界 right = mid

;如果a[mid] >= a[left],表明處於遞增a,因此調整左邊界left = mid

。當左右邊界相鄰時,較小的乙個就是陣列的最小值。其實,對於一般情況,右邊界所指的元素為最小值。

對於特殊情況,即旋轉個數為0。按照上述演算法,右邊界會不斷減少,直到與左邊界相鄰。這時左邊界所指的元素為最小值。下面給出幾組測試案例:

//   1

// 1

// 1

// 1

// 9 錯誤

第五組的結果是錯誤的。其實,上述演算法適用於嚴格遞增的陣列,對於非嚴格遞增,用二分法無法保證正確解。有興趣的讀者,可以試試,對於非嚴格遞增的序列,是否可以用二分法得到正確解。

參考**:

//函式功能 : 旋轉陣列的最小元素  

//函式引數 : parray指向陣列,len為陣列長度

//返回值 : 最小元素

int findmin(int *parray, int len)

return parray[right] > parray[left] ? parray[left]: parray[right];

}

旋轉陣列中的最小元素

題目 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個排好序的陣列的乙個旋轉。輸出旋轉陣列的最小值。舉例 輸入陣列為的乙個旋轉,該陣列的最小值為1。答 include stdafx.h include using namespace std 查詢旋轉陣列中的最小元素 int...

旋轉陣列中找出最小數

把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。public static int min int a int left 0 int right a.length 1 if a le...

旋轉陣列的最小元素

題目 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個排好序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。解題 類似二分查詢,使用兩個指標 left right 指向一前一後,一般情況下arr left 一定大於等於arr right ...