154. 寻找旋转排序数组中的最小值 II
二分法边界条件
另外二分法返回是start或者end,返回的条件就是start=end
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] > nums[right]: left = mid + 1
elif nums[mid] < nums[right]: right = mid
else: right = right - 1 # key,这步是因为有重复才加的
return nums[left]
对于这题,题解考虑到如果不加else,解决不了的案例是 [1, 0, 1, 1, 1]和[1,0,1,1,1] 这样的,而不是其他的简单[3,0,1,1,4]案例
我们采用 right = right - 1 解决此问题,因为:
1.此操作不会使数组越界:因为迭代条件保证了 right > left >= 0;
2.此操作不会使最小值丢失:假设 nums[right]是最小值,有两种情况:
若 nums[right]是唯一最小值:那就不可能满足判断条件 nums[mid] == nums[right],因为 mid < right(left != right 且 mid = (left + right) // 2 向下取整);
若 nums[right]不是唯一最小值,由于 mid < right 而 nums[mid] == nums[right],即还有最小值存在于 [left, right - 1]区间(如right-1),因此不会丢失最小值。