刷題筆記6——輸出旋轉陣列的最小元素
阿新 • • 發佈:2018-11-08
題目描述
把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{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);
}
};