JZ6 旋转数组的最小数字
my version
时间复杂度O(n)
错误记录
- 特殊样例:数组未进行旋转如[1,2,3] 找最小 1
class Solution:
def minNumberInRotateArray(self, rotateArray):
if rotateArray:
for i in range(1, len(rotateArray)):
if rotateArray[i-1]>rotateArray[i]:
return rotateArray[i]
return rotateArray[0]
return 0
book method
利用旋转数组的特性,可分为两段排好序的数组,可用二分查找法,时间复杂度O(logN)
class Solution:
def find_min_inorder(self, array, start, end):
for i in range(start, end):
if array[i] < array[start]:
return array[i]
return array[start]
def minNumberInRotateArray(self, rotateArray):
if rotateArray:
start_idx = 0
end_idx = len(rotateArray)-1
while start_idx < end_idx:
if rotateArray[start_idx] < rotateArray[end_idx]:
# 无旋转的排序数组
return rotateArray[start_idx]
else:
# 旋转数组(包含两段排好序的数组)
if start_idx+1 == end_idx:
return min(rotateArray[end_idx], rotateArray[start_idx])
mid_idx = (end_idx - start_idx) // 2 + start_idx
if rotateArray[mid_idx] == rotateArray[start_idx] and rotateArray[mid_idx] == rotateArray[end_idx]:
# 无法区分两段排好序的数组
return self.find_min_inorder(rotateArray, start_idx, end_idx)
elif rotateArray[mid_idx] > rotateArray[end_idx]:
# 最小值在后半段,前半段已排好序
start_idx = mid_idx
elif rotateArray[mid_idx] < rotateArray[start_idx]:
# 最小值在前半段,后半段已排好序
end_idx = mid_idx
return 0
算法流程:
1、初始化: 声明 start, end分别指向 array 数组左右两端
2、循环二分: 设 mid = (start + end) / 2 为每次二分的中点( “/” 代表向下取整除法,因此恒有 start≤mid
- 当 array[mid] > array[start] 时: mid一定在左排序数组 中,即旋转点 x 一定在 [mid + 1, end] 闭区间内,因此执行 start = mid + 1
- 当 array[mid] < array[end] 时: mid一定在右排序数组 中,即旋转点 x 一定在[start, mid]闭区间内,因此执行 end = mid
- 当 array[mid] = array[end] 时: 无法判断 mid在哪个排序数组中,即无法判断旋转点 x 在 [start, mid] 还是 [mid + 1, end] 区间中。解决方案: 执行 j = j - 1 缩小判断范围
3、返回值: 当 start = end 时跳出二分循环,并返回 旋转点的值 array[start] 即可。
参考代码
def minNumberInRotateArray(self, rotateArray):
if rotateArray:
start = 0
end = len(rotateArray)-1
while start < end:
mid = (start + end) // 2
if rotateArray[mid] > rotateArray[end]:
# mid在前半段有序数组中
start = mid+1
elif rotateArray[mid] < rotateArray[start]:
# mid在后半段有序数组中 后半段有序数组中的最小值一定是第一个数
end = mid
elif rotateArray[mid] == rotateArray[end]:
end -= 1
return rotateArray[start]
return 0