LeetCode.154 - 寻找旋转排序数组中的最小值 II(二分思想)

Posted Booksort

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode.154 - 寻找旋转排序数组中的最小值 II(二分思想)相关的知识,希望对你有一定的参考价值。

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

方法一:暴力解法

这个十分暴力,就是依次去遍历,然后元素之间比较大小。时间复杂度O(N),代码简单。

方法二:二分思想

利用二分的思想可以加速查找,因为二分每次判断都会丢弃一般的数据量。虽然这个数组不是有序的,但是部分有序的。

可以由于题目的特性
可能会出现,[0,n/2+a]区间都是升序的(a∈[−n/2,n/2])。
理解一下就是左半边区间是可能是有序的,也可能是右半区间是有序的。所以,我们可以考虑使用mid=(left+right)>>1来判断。
对于二分算法而言,有三种情况

  1. 如果出现了v[left]<v[right]的情况,那么这个说明着个区间是有序的,最小值就是v[left]
  2. v[mid]在v[right]前面,如果v[mid]大于v[right],那么可以得知,最小值在一定在[mid-1,right]区间中
  3. 如果v[mid]<v[right],说明最小值在[left,mid]区间中,mid也可能是最小值。
  4. 如果v[mid]=v[right],那么,说明这个数组出现了未知情况,就可以考虑暴力缩减其区间长度,不然根本就没有判断的依据,只能贪心思想。

这个区间的目的就是将最小值圈在区间内,保证最小值一定在[left,right]的区间内

将数组数形相结合,大概就这几种情况

对这些模型进行分析,都被包含在了四种判断条件的范围内。
代码实现

class Solution 
public:
    int findMin(vector<int>& nums) 
        int left=0;
        int right=nums.size()-1;
        while(left<right)
        
            if(nums[left]<nums[right])//有序的区间
                return nums[left];
            int mid=(left+right)>>1;
            if(nums[mid]<nums[right])
                right=mid;
            else if(nums[mid]>nums[right])
                left=mid+1;
            else//贪心,暴力缩减区间长度
                left++;
        
        return nums[left];
    
;

感谢各位大佬观看

以上是关于LeetCode.154 - 寻找旋转排序数组中的最小值 II(二分思想)的主要内容,如果未能解决你的问题,请参考以下文章

寻找旋转排序数组中的最小值

二分法08:寻找旋转排序数组中的最小值

159. 寻找旋转排序数组中的最小值

lintcode:寻找旋转排序数组中的最小值 II

153. 寻找旋转排序数组中的最小值

leetcode(153)---寻找旋转排序数组中的最小值(二分查找)