LeetCode 154. 寻找旋转排序数组中的最小值 II

解题思路

二分查找变形+递归,是第153题的延伸题目(允许数组有重复元素)

由题意得,nums数组共有两种情况:

  1. 分为左右两段非降序数组,且左整体上大于右;
  2. 一整个非降序数组;

循环体中以中间值与两端点值比较作判断,分五种情况:

  1. 中间值小于左端时,表明nums数组处于第一种情况,且中间值位于第二段数组,最小元素必在左半边(包括中间值),如:[1,2,0,1,1],[2,0,1,1,1];
  2. 中间值大于右端时,表明nums数组处于第一种情况,且中间值位于第一段数组,最小元素必在右半边(不包括中间值),如:[1,1,1,0,0],[1,2,3,4,0];
  3. 中间值等于左端且小于右端时,表明nums数组处于第二种情况,最小元素即左端点,如:[0,0,0,1,2];
  4. 中间值等于右端且大于左端时,表明nums数组处于第二种情况,最小元素即左端点,如:[0,1,2,2,2];
  5. 中间值与两端均相等时,无法判断nums处于哪种情况,需要递归对两边分别二分查找,如:[1,1,1,0,1],[1,0,1,1,1],[1,1,1,1,1]。
class Solution {
public:
    int Min_l_r(vector<int>& nums,int l,int r) {
        if(l == r) return nums[l];
        while(r - l > 1) {
            int mid = (l+r)/2;
            if(nums[mid] < nums[l]) r = mid;
            else if(nums[mid] > nums[r]) l = mid+1;
            else if(nums[mid] == nums[l] && nums[mid] < nums[r]) return nums[l];
            else if(nums[mid] == nums[r] && nums[mid] > nums[l]) return nums[l];
            else return min(Min_l_r(nums,l,mid-1),Min_l_r(nums,mid+1,r)); //if(nums[mid] == nums[l] && nums[mid] == nums[r])
        }
        return min(nums[l],nums[r]);
    }
    int findMin(vector<int>& nums) {
        return Min_l_r(nums,0,nums.size()-1);
    }
};

平均时间复杂度O(logN),最坏时间复杂度O(N)(数组内全为同一元素时)。
空间复杂度O(1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值