1. 程式人生 > >LeetCode 153, 154. Find Minimum in Rotated Sorted Array I & II

LeetCode 153, 154. Find Minimum in Rotated Sorted Array I & II

153. Find Minimum in Rotated Sorted Array

二分題目,由於rotated存在,a[mid]<key不能判斷在哪一邊搜尋。

可以根據a[low]與a[high]的關係,來判斷哪一邊有序,哪一邊存在rotate,進而縮小搜尋區間。

 

開區間寫法:(由於搜尋區間和解區間都是[low, high],直接 [low, high])

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

 

上面的寫法是用 a[mid] 與 a[high] 比較的,這樣是比與 a[low] 比較要好的。如果和 a[low] 比較,需要注意的是 a[low]=a[mid] 可能發生,由於沒有重複元素,這種情況只可能在 low==mid 時發生,即 low=mid=high-1 時。由於上面 a[low]<a[high] 就會return,說明這裡 a[low]>a[high],應該返回 high 的值,因此歸類歸到 a[low]<a[mid] 一類中。

這道題的followup,如果有重複元素,a[low]==a[mid] 即有可能是 low==mid 這一邊界情況,也有可能是重複元素導致的 a[low]==a[mid],需要分別處理,比較繁瑣。

而與 a[high] 比較,a[mid]==a[high] 只可能是重複元素導致的。

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

 

 

154. Find Minimum in Rotated Sorted Array II

有duplicate以後,nums[mid]==nums[high] 的情況就會發生,我們無法判斷最小值是左邊還是右邊。

由於二分實質是維護low,high只是用來縮小區間,我們可以 --high,這樣並不會把最小的元素skip掉。

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

 

 

 

類似題目:

Search in Rotated Sorted Array

 

reference:

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