C++實現LeetCode(154.尋找旋轉有序數組的最小值之二)

[LeetCode] 154. Find Minimum in Rotated Sorted Array II 尋找旋轉有序數組的最小值之二

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e.,  [0,1,2,4,5,6,7] might become  [4,5,6,7,0,1,2]).

Find the minimum element.

The array may contain duplicates.

Example 1:

Input: [1,3,5]
Output: 1

Example 2:

Input: [2,2,2,0,1]
Output: 0

Note:

  • This is a follow up problem to Find Minimum in Rotated Sorted Array.
  • Would allow duplicates affect the run-time complexity? How and why?

這道尋找旋轉有序重復數組的最小值是之前那道 Find Minimum in Rotated Sorted Array 的拓展,當數組中存在大量的重復數字時,就會破壞二分查找法的機制,將無法取得 O(lgn) 的時間復雜度,又將會回到簡單粗暴的 O(n),比如這兩種情況:{2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2} 和 {2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2},可以發現,當第一個數字和最後一個數字,還有中間那個數字全部相等的時候,二分查找法就崩潰瞭,因為它無法判斷到底該去左半邊還是右半邊。這種情況下,將右指針左移一位(或者將左指針右移一位),略過一個相同數字,這對結果不會產生影響,因為隻是去掉瞭一個相同的,然後對剩餘的部分繼續用二分查找法,在最壞的情況下,比如數組所有元素都相同,時間復雜度會升到 O(n),參見代碼如下:

解法一:

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = (int)nums.size() - 1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[right]) left = mid + 1;
            else if (nums[mid] < nums[right]) right = mid;
            else --right;
        }
        return nums[right];
    }
};

跟之前那道 Find Minimum in Rotated Sorted Array 一樣,還是可以用分治法 Divide and Conquer 來解,不過寫法跟之前那道略有不同,隻有在 nums[start] < nums[end] 的時候,才能返回 nums[start],等於的時候不能返回,比如 [3, 1, 3] 這個數組,或者當 start 等於 end 成立的時候,也可以直接返回 nums[start],後面的操作跟之前那道題相同,每次將區間 [start, end] 從中間 mid 位置分為兩段,分別調用遞歸函數,並比較返回值,每次取返回值較小的那個即可,參見代碼如下:

解法二:

class Solution {
public:
    int findMin(vector<int>& nums) {
        return helper(nums, 0, (int)nums.size() - 1);
    }
    int helper(vector<int>& nums, int start, int end) {
        if (start == end) return nums[start];
        if (nums[start] < nums[end]) return nums[start];
        int mid = (start + end) / 2;
        return min(helper(nums, start, mid), helper(nums, mid + 1, end));
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/154

類似題目:

Find Minimum in Rotated Sorted Array

參考資料:

https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/

https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/discuss/48808/My-pretty-simple-code-to-solve-it

https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/discuss/167981/Beats-100-Binary-Search-with-Explanations

到此這篇關於C++實現LeetCode(154.尋找旋轉有序數組的最小值之二)的文章就介紹到這瞭,更多相關C++實現尋找旋轉有序數組的最小值之二內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: