leetcode 154. Find Minimum in Rotated Sorted Array II (hard)

154. Find Minimum in Rotated Sorted Array II
题目描述

Suppose an array sorted in ascending order 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.

解题思路

类似 leetcode 153. Find Minimum in Rotated Sorted Array
但是数组可以存在重复的数. 这样就增加判断的难度, 在153题中, 只要简单判断nums[mid]和nums[tail]的大小就可以决定left或者right往哪边收缩边界. 但是存在重复的情况下, 可能存在nums[mid] == nums[tail]或者nums[mid] == nums[head]的情况.

这里总结一下比153题多需要考虑的几种情况:
()在判断收缩边界条件为 if nums[mid] == nums[tail]的情况下)

  1. 数组全是重复数, 如 [2,2,2,2,2,2]
  2. 旋转位置在重复数中, 其他数在左半部分: [1,1,0,1,1,1,1,1]
  3. 旋转位置在重复数中, 其他数在右半部分: [1,1,1,1,1,0,1,1]
  4. 旋转位置在重复数的末尾(这样判断仍然是nums[mid] == nums[tail]) : [2,3,0,1,1,1,1,1]
  5. 因为我们这里考虑的是, nums[mid]和最右一个元素的大小, 因此不考虑旋转位置在重复数起始的情况: [3,3,3,3,0,1,1,2]

这里用到的判断一个数组是否重复的方法就是 判断if max(list) == min(list).

代码

class Solution:
    def findMin(self, nums: List[int]) -> int:
        if len(nums) == 0:
            return 0
        if len(nums) == 1:
            return 1
        
        left = 0
        right = len(nums) - 1
        
        # 递增序列
        if nums[left] < nums[right]:
            return nums[0]
        # 1. 数组全是重复数
        if max(nums) == min(nums):
            return nums[0]
        
        while left <= right:
            mid = left + (right - left)//2
            if nums[mid] > nums[right]:
                left = mid + 1
            elif nums[mid] < nums[right]:
                right = mid - 1
                
            elif nums[mid] == nums[right]:
                # 旋转位置在重复数中
                if nums[mid] == nums[left]:
                	# 2. 其他数在左半部分
                    if max(nums[0:mid]) != min(nums[0:mid]):
                        right = mid - 1
                    # 3. 其他数在右半部分
                    else:
                        left = mid + 1
                # 4. 旋转位置在重复数的末尾
                else:
                    right = mid - 1
                    
            if nums[mid-1] > nums[mid]:
                return nums[mid]
            if nums[mid] > nums[mid+1]:
                return nums[mid+1] 
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值