1. 程式人生 > >刷題筆記6——輸出旋轉陣列的最小元素

刷題筆記6——輸出旋轉陣列的最小元素

題目描述

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

1、常規方法

遍歷陣列的每一個元素,如果發現有比最小值小的,就把那個值賦給它即可。時間複雜度顯然是O(N)

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if
(0 == rotateArray.size()) { return 0; } int min = rotateArray[0]; for(auto i : rotateArray) { if(i < min) min = i; } return min; } };

2、二分法

常規方法沒有利用題目所給的輸入陣列的特性。下面分析二分法
由題意可以知道,旋轉之後的陣列有下面的特點:
① 可以分為兩個已經排好序的子陣列。
② 前面的子陣列的元素均大於後面的子陣列的元素。
③ 最小的元素是這兩個子陣列的分界。
這時候,就可以利用兩個哨兵指標,分別指向陣列的第一個元素和最後一個元素

這時候,取中間的元素,

如果中間的元素位於前面的子陣列,那麼該中間元素肯定
大於等於第一個元素(這作為改變指標的條件),並且要找的最小值肯定在中間元素的右邊
於是令 left 指向中間元素
在這裡插入圖片描述

如果中間的元素位於後面的子陣列,那麼該中間元素肯定
小於等於最後一個元素(這作為改變指標的條件),並且要找的最小值肯定在中間元素的左邊
於是令 right指向中間元素
在這裡插入圖片描述

這樣不斷地進行比較,這樣,
哨兵left將會指向前面子陣列的最後一個元素,
哨兵right將會指向後面子陣列的第一個元素。
即他們最終的差值是1。這作為迴圈終止的條件
而哨兵right指向的就是最小的元素。

class Solution {
public: int minNumberInRotateArray(vector<int> rotateArray) { if(0 == rotateArray.size()) { return 0; } int left = 0; int right = rotateArray.size() - 1; int mid = -1; // 若滿足條件,則說明已經是非遞減序列,直接返回第一個元素 if(rotateArray.at(left) < rotateArray.at(right)) { return rotateArray.at(left); } while(left < right) { if(right - left == 1) { mid = right; break; } int mid = (left + right) / 2; if(rotateArray.at(mid) >= rotateArray.at(left)) { left = mid; } if(rotateArray.at(mid) <= rotateArray.at(right)) { right = mid; } } return rotateArray.at(mid); } };