leetcode——Find Minimum in Rotated Sorted Array II

題目一:

Suppose a sorted array 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.

You may assume no duplicate exists in the array.

分析:

二分查找,始終確保first在第一遞增部分,last在第二遞增部分即可。通過判斷nums[mid]的大小判斷mid屬於第一部分還是第二部分,然後更新first或者last,逐步縮小first和last的距離,直到它們相鄰。

class Solution {
public:
    int findMin(vector<int>& nums) {
        if (nums[0] < nums[nums.size() - 1])//遞增序列,旋轉0個元素 
        {
            return nums[0];
        }
        int first = 0, last = nums.size() - 1;//first始終在第一部分,last始終在第二部分
        while (last - first > 1) 
        {
            int mid = first + (last - first) / 2;
            if (nums[mid] > nums[first])//mid在第一段
            {
                first = mid;
            }
            else //mid在第二段
            {
                last = mid;
            }
        }
        //last和first相鄰或者重合
        return min(nums[first], nums[last]);
    }
};

題目二:

Suppose a sorted array 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.

分析:

跟上一題不同的是數組中可能存在相同元素,要想使用二分查找還得維護“始終確保first在第一遞增部分,last在第二遞增部分”這個不變式。只有當nums[first] == nums[mid] == nums[last]的時候不好確定mid到底屬於第一部分還是第二部分,因此沒法更新first和last,這種情況只能採用順序遍歷的方式查找最小值。

class Solution {
public:
    int findMin(vector<int>& nums) {
        if (nums[0] < nums[nums.size() - 1])//遞增序列,旋轉0個元素 
        {
            return nums[0];
        }
        int first = 0, last = nums.size() - 1;//first始終在第一部分,last始終在第二部分
        while (last - first > 1) 
        {
            int mid = first + (last - first) / 2;
            
            if (nums[first] == nums[last]) 
            {
                if (nums[mid] == nums[first]) 
                {
                    //遍歷
                    return *min_element(nums.begin() + first, nums.begin() + last);
                }
                else if (nums[mid] > nums[first]) 
                {
                    first = mid;
                }
                else 
                {
                    last = mid;
                }
            }
            else //nums[first]必然大於nums[last]
            {
                if (nums[mid] >= nums[first]) //這裏允許nums[mid] == nums[first]
                {
                    first = mid;
                }
                else 
                {
                    last = mid;
                }
            }
        }
        //last和first相鄰或者重合
        return min(nums[first], nums[last]);
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章