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]的情况下)
- 数组全是重复数, 如 [2,2,2,2,2,2]
- 旋转位置在重复数中, 其他数在左半部分: [1,1,0,1,1,1,1,1]
- 旋转位置在重复数中, 其他数在右半部分: [1,1,1,1,1,0,1,1]
- 旋转位置在重复数的末尾(这样判断仍然是nums[mid] == nums[tail]) : [2,3,0,1,1,1,1,1]
- 因为我们这里考虑的是, 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]