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]