Leetcode: Find Minimum in Rotated Sorted Array

原題鏈接:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/

我在github上的leetcode倉庫:https://github.com/cooljacket/leetcodes

題意

定義翻轉有序數組:一個升序數組,從中間某個元素切開,把左右兩部分互換位置。
比如[1, 2, 3, 4, 5, 6, 7]從3處切開成爲[1, 2, 3]和[4, 5, 6, 7],兩部分互換位置,變成[4, 5, 6, 7, 1, 2, 3]。

給定這樣一個數組,要求找出其中最小的元素出來!

這一題的要求比較簡單,輸入沒有重複的元素;
有重複元素的版本見:http://blog.csdn.net/Jacketinsysu/article/details/52299291

思路

這樣的數組的特徵是很明顯的,就是如下圖所示的趨勢:

細節1

用二分查找的思路很直接,需要確定的細節就是:如何移動左右端?

用low,high和mid分別表示左端、右端和區間中點。
如果mid是落在A區的話,很明顯有nums[mid] > nums[high],反之亦然。
若mid是落在B區的,則有nums[mid] < nums[high],反之亦然。

當mid落在A區時,很明顯可以low = mid + 1;
當mid落在B區時,只能high = mid。爲什麼不能mid - 1呢?因爲如此時mid剛好指向的是最小值,-1就過頭了!

細節2

其實還有一個細節,就是mid的計算,它有兩個方法:
1)mid = (low + high) >> 1;
2)mid = (low + high + 1) >> 1;
這兩種計算方法具體會產生什麼不同的效果呢?

其實有經驗的人就會知道,二分查找過程中,最最關鍵的地方,就是收斂到最後只剩下兩個元素的時候,怎麼取捨,決定了mid要偏左還是偏右!(這裏說得有點懸,改天再寫一篇二分查找的專題)

這裏舉個簡單的例子就好了,比如最後的區間是這樣的:[1, 0],然後如果用的是第二種計算mid的方法,就會死循環了,因爲mid一直會等於high!而high在比較過後又會變成mid,一直不變!

代碼

沒有重複的元素,代碼很簡單:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int low = 0, high = nums.size() - 1, mid;
        while (low < high) {
            mid = (low + high) >> 1;
            if (nums[mid] > nums[high])
                low = mid + 1;
            else
                high = mid;
        }
        return nums[low];
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章