154. 寻找旋转排序数组中的最小值II(Find Minimum in Rotated Sorted ArrayII)

154. 寻找旋转排序数组中的最小值II(Find Minimum in Rotated Sorted ArrayII)

题解

旋转排序数组由两个有序子序列构成。

二分法

  1. 初始化左指针 l = 0 l=0 l=0,右指针 r = n − 1 r=n-1 r=n1

  2. 循环条件 l < r l<r l<r

    • m i d = ( l + r ) / / 2 mid=(l+r)//2 mid=(l+r)//2
    • n u m s [ m i d ] > n u m s [ r ] nums[mid]>nums[r] nums[mid]>nums[r]。说明 m i d mid mid一定在第一个有序数组中。则最小值一定在第二个有序数组中,令 l = m i d + 1 l=mid+1 l=mid+1
    • n u m s [ m i d ] < n u m s [ r ] nums[mid]<nums[r] nums[mid]<nums[r]。说明 m i d mid mid已经在第二个有序数组中。则最小值为 m i d mid mid m i d mid mid左侧。令 r = m i d r=mid r=mid
    • n u m s [ m i d ] = = n u m s [ r ] nums[mid]==nums[r] nums[mid]==nums[r]。此时令 r = r − 1 r=r-1 r=r1
  3. 返回 n u m s [ l ] nums[l] nums[l]

**注意!**算法中两个疑惑点:
1.为什么要用 n u m s [ m i d ] nums[mid] nums[mid] n u m s [ r ] nums[r] nums[r]比较,而不是和 n u m s [ l ] nums[l] nums[l]比较。
因为是寻找最小值,看如下例子:
[ 1 , 2 , 3 , 4 , 5 ] [1,2,3,4,5] [1,2,3,4,5]
[ 2 , 3 , 4 , 5 , 1 ] [2,3,4,5,1] [2,3,4,5,1]
虽然 n u m s [ m i d ] nums[mid] nums[mid]都大于 n u m s [ l ] nums[l] nums[l],但是最小值可以在左侧或者右侧。
2.在 n u m s [ m i d ] = = n u m s [ r ] nums[mid]==nums[r] nums[mid]==nums[r],为什么令 r = r − 1 r=r-1 r=r1
例子: [ 1 , 1 , 1 , 3 , 1 ] [1,1,1,3,1] [1,1,1,3,1]
假设 n u m s [ r i g h t ] nums[right] nums[right]是最小值,有两种情况:
n u m s [ r i g h t ] nums[right] nums[right]是唯一最小值:则不能满足判断条件 n u m s [ m i d ] = = n u m s [ r i g h t ] nums[mid] == nums[right] nums[mid]==nums[right],因为 m i d < r i g h t mid < right mid<right l e f t ! = r i g h t left != right left!=right m i d = ( l e f t + r i g h t ) / / 2 mid = (left + right) // 2 mid=(left+right)//2 向下取整);
n u m s [ r i g h t ] nums[right] nums[right] 不是唯一最小值,由于 m i d < r i g h t mid < right mid<right n u m s [ m i d ] = = n u m s [ r i g h t ] nums[mid] == nums[right] nums[mid]==nums[right],即还有最小值存在于 [ l e f t , r i g h t − 1 ] [left, right - 1] [left,right1] 区间,因此不会丢失最小值。引自

复杂度分析

  • 时间复杂度: O ( l o g ( n ) ) O(log(n)) O(log(n))
  • 空间复杂度: O ( 1 ) O(1) O(1)

Python

class Solution:
    def findMin(self, nums: List[int]) -> int:
        if(not nums):
            return None
        n=len(nums)
        if(n==1):
            return nums[0]
        l=0
        r=n-1
        while(l<r):
            mid=(l+r)//2
            if(nums[mid]>nums[r]):
                l=mid+1
            elif(nums[mid]<nums[r]):
                r=mid
            else:
                r=r-1
        return nums[l]

Java(待完成)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值