Leetcode:Find Minimum in Rotated Sorted Array II

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

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

題意

這道題的第一個版本已經寫了博客:http://blog.csdn.net/Jacketinsysu/article/details/52299090

第二版本只是多了一個限制:數組裏可以有重複的元素

思路

用low,high和mid分別表示左端、右端和區間中點。

如下圖所示,當nums[mid] == nums[high]爲true時,該怎麼辦呢?這個時候,最小值可能位於區間[mid1, high]上,也可能位於[low, mid2]上。

《劍指offer》的策略

在區間[low, high]上線性查找,這的確不會錯過,也可行,不過寫起來麻煩,代碼長了好多行。

我的策略

我的方法也是線性查找,不過不是在[low, high]之間,而是簡單–high就好了!

首先,–high是否能夠解決這個問題?相當於從右邊縮減查找區間的範圍,這確實是可行的,也不會遺漏。

其次,爲什麼不++low呢?舉個例子:{4, 4, 4, 4, 0, 1, 1}
第一次查找:[0, 6],mid=3,nums[3] = 4 > nums[high],所以low變成mid+1=4;
第二次查找:[4, 6],mid=5,nums[5] = 1 == nums[high],這個時候++low嗎????那查找區間就變成[5, 6]了,錯過了最小值了。。。

那到底是爲什麼不能++low呢?原因在於我們是拿nums[mid]和nums[high]去做比較的,跟nums[low]沒有一毛錢的直接關係,所以不能用右區間的情況來決定左區間的動態。

說直觀點,就是,比如張三偷東西了,警察來了,人贓俱獲,然後把李四給抓走了,你說冤不冤,哈哈~

性能

最後,評價一下我這個方法的性能,最差的情況也是O(n)的,不過平均情況要比上面的策略好,至於爲什麼就不用多說了吧?(因爲不是一遇到相等的情況就“無腦線性找”,而是進一步,看看能不能繼續做折半查找,見下面的代碼)。

代碼

豬一般的優雅,哈哈!

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 if (nums[mid] < nums[high])
                high = mid;
            else // 沒錯,就是這麼簡單!
                --high;
        }
        return nums[low];
    }
};

╭︿︿︿╮
{/ o o /}
( (oo) )
︶ ︶︶
另,如果要跟《劍指offer》裏的做法一樣的話,也行,得寫這……麼長:

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[low] && nums[mid] == nums[high])
                return linearSearch(nums, low, high);
            if (nums[mid] > nums[high])
                low = mid + 1;
            else if (nums[mid] < nums[high])
                high = mid;
            else
                --high;
        }
        return nums[low];
    }

private:
    int linearSearch(const vector<int>& nums, int low, int high) {
        int minNum = nums[low];
        for (int i = low+1; i <= high; ++i) {
            if (nums[i] < minNum)
                minNum = nums[i];
        }
        return minNum;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章