如下图所示,寻找旋转数组的最小元素即为寻找 右排序数组 的首个元素 nums[x] ,称 x为 旋转点
算法流程:
1.初始化: 声明 i, j双指针分别指向 nums 数组左右两端。
2.循环二分: 设 m=(i+j) //2 为每次二分的中点
可分为以下三种情况:
当 nums[m]>nums[j] 时: m一定在 左排序数组 中,即旋转点 x 一定在 [m+1,j]闭区间内,因此执行i = m + 1。
当nums[m]<nums[j] 时: m 一定在 右排序数组 中,即旋转点 x 一定在[i,m] 闭区间内,因此执行 j = m。
当 nums[m]=nums[j] 时: 无法判断 m 在哪个排序数组中,即无法判断旋转点 x在 [i,m]还是 [m+1,j][ 区间中。解决方案: 执行 j = j − 1 缩小判断范围。
代码:
"""
查找旋转数组后的最小值
"""
nums = [5,5,5,5,6,7,0,1,2,3,4]
# 0,1,2,3,4,5,6,7,8,9,10
def findMin(nums):
i = 0
j = len(nums) - 1
while i < j:
m = (i + j) // 2
if nums[m] > nums[j]:
i = m + 1
elif nums[m] < nums[j]:
j = m
else:
j -= 1 #return min(nums[i:j])
return nums[i]
minIndex = findMin