面試題11 旋轉陣列的最小數字

2021-10-06 21:23:04 字數 1565 閱讀 8057

題目

把乙個陣列最開始的若干元素搬到陣列的末尾,稱之為陣列的旋轉。 輸入乙個排序好了的遞增陣列的旋轉,要求輸出旋轉陣列的最小元素。

如輸入:[5,7,1,2,3]

輸出:1

注意是否包含重複元素

演算法思路為了追求演算法高效,減低複雜度,如果單單是找出最小元素,直接遍歷一遍就可有得出,時間複雜度為o(n ),而很顯然本題需要的不是該方法,有比挨個遍歷陣列更高效的方法,下面來分析題目,陣列將原本已經公升序排序好的陣列通過分割,分割成為兩部分,而左邊那部分變為右邊部分,如下圖:

通過上圖分析,可以使用二分法,步驟如下:設定兩個指標l ,r, 分別指向陣列nums的兩端,迴圈二分,定義乙個mid為每次二分的中點,必有 l <= mid < r,有如下三種情況:

當nums[mid] > nums[r],例如[5,6,7,1,2],nums[mid] 大於nums[r],說明最小元素必然在mid的右邊,此時更新 l 的值,l = mid+1,繼續迴圈二分 ;

當nums[mid] < nums[r],例如[7,1,2,3,4],nums[mid] < nums[r],說明最小元素必然mid的左邊,當然也有可能最小元素就是mid,如[5,7,1,2,3]就是如此,所以,此時更新r的值,r = mid,繼續二分;

當nums[mid] = nums[r]時,說明出現重複資料,不能夠判斷最小元素的位置,所以此時縮小範圍,r自減1,再繼續二分查詢。

當 l = r 時,退出迴圈,返回結果,即為nums[l]。

**

class

solution

else

if(nums[r]

< nums[mid]

)else r--;}

return nums[l];}

}

時間複雜度:o(logn),空間複雜度:o(1),只引入了常數個變數。

至此題目解答了,但仍然有兩個點值得思考:一是為什麼是nums[mid] 和 nums[r]比較,而不是nums[mid] 和 nums[l];二是重複元素的處理是r–。下面一一解答。

**問題一:**前面圖中已經分析的很清楚,左右兩個排序的陣列中,最小元素必然在右排序陣列中,若和mid和 l 出的值作比較,當nums[mid] > nums[l] 時,無法判斷最小值在哪邊,也就是無法判斷mid在哪個排序陣列,本質就是 r 的初始值必然在右排序陣列中,而 l 則無法確定。如[4,5,6,1,2],就無法判斷。

**問題二:**重複元素的處理。即當nums[mid] = nums[r] ,無法判斷mid在左右哪個排序陣列中,也就無法判斷最小元素的位置,所以,需要縮小搜尋範圍,r 自減1,可能你會說,既然nums[mid] = nums[r] ,那就是說從mid 處的元素到 r 處的元素都相等,那就錯了,如:[3,3,1,3]這種情況就不等。所以需要r–。

面試題11 旋轉陣列的最小數字

題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。解題思路 輸入的陣列為非減排序陣列的旋轉,陣列分為兩個排好序的陣...

面試題11 旋轉陣列的最小數字

題目描述 把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。note 給出的所有元素都大於0,若陣列大小為0,請返回0。類似二分查詢,旋轉陣列由兩個有序陣列組成 class solut...

面試題11 旋轉陣列的最小數字

把乙個陣列最開始若干個元素搬到陣列的末尾 一般方法遍歷,o n 將這個陣列看作是兩個排序陣列 利用二分查詢的思想,比較中間的數字與兩頭 如果中間元素位於第乙個遞增陣列,大於 等於第乙個指標,範圍 右邊 如果中間元素位於後面遞增陣列,它應該小於 等於第二個指標 左邊 注意改變後指向中間元素 最後結果是...