题目描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
方法一:二分法变形 (剑指Offer)
数组的最小数字将数组分为两个递增数组,最小数字是两个数组的分界线。
下面根据中间元素位置分两种情况:
1.如果中间元素mid位于左侧的递增数组,则array[mid]>array[low],且最小数字位于mid右侧,设置low=mid
2.如果中间元素mid位于右侧的递增数组,则array[mid]<array[high],且最小数字位于mid左侧,设置high=mid
最后low和high会指向两个相邻的元素,选择其中较小的数作为min
tips:判断是要先判断mid位于左侧的情况,因为mid位于左侧递增数组时也会有array[mid]<array[high]情况出现
需要考虑特殊情况:
1.数组为空,返回0
2.一般情况下,array[low]要大于array[high],但当旋转0个元素时,array[low]小于array[high],此时array[low]即为数组的最小数字
3.当数组array[low] = array[mid] = array[high]时,无法判断mid位于哪个递增数组,此时需要进行顺序查找
例:
1 0 1 1 1 此时中间元素位于左侧递增数组
1 1 1 0 1 此时中间元素位于右侧递增数组
tips:注意是否需要有等号
def getMin(rotateArray):
if not rotateArray: #empty rotateArray
return 0
low = 0
high = len(rotateArray)-1
if rotateArray[low] < rotateArray[high]: # rotate zero element
return rotateArray[low]
minvalue = rotateArray[0]
while rotateArray[low] >= rotateArray[high]:
if low == high-1:
if rotateArray[low] <= rotateArray[high]:
return rotateArray[low]
else:
return rotateArray[high]
mid = int((low + high) / 2)
if rotateArray[low] == rotateArray[high] == rotateArray[mid]: # low = mid =high search sequential search
for i in range(len(rotateArray) - 1):
if rotateArray[i] < minvalue:
minvalue = rotateArray[i]
return minvalue
if rotateArray[mid] >= rotateArray[low]:
low = mid
elif rotateArray[mid] <= rotateArray[high]:
high = mid