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

猜你喜欢

转载自www.cnblogs.com/hankunyan/p/9926554.html