题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
python实现:
方法一:二分查找法:
思路:首先判断数据长度是否为0,如果为0,返回0
如果不为0:
进行二分查找,二分查找每次有两种情况:当前的mid是我们找的最小值,(根据这个值是不是大于前一个值判断)和当前的mid不是我们找的最小值
第一种情况直接输出
第二种情况需要判断我们找的值在当前值的左边还是右边,此时又有三种情况:
(1)当前值大于top位置的值:说明我们需要找的值在当前值的右边,bot=mid+1
(2)当前值小于top位置的值,说明我们需要找的值在当前值的左边,top=mid-1
(3)当前值等于top位置的值:此时无法判断在左边还是右边,就缩小寻找的范围,也就是bot-=1;top-=1
最终循环的结果要么是:top=bot+1,这种情况如果top为需要寻找的数据,找到数据,结束循环;如果bot为需要寻找的数据,则变成第二种结果,也就是top==bot,这种情况直接返回top位置的值
写程序时边界条件需要注意:这里的边界条件包括:rotateArray[mid]<rotateArray[mid-1]这里的mid-1,当mid=0时会使得mid-1<0,因为mid是向上取整得到的,所以避免了这种情况,还有需要考虑的边界条件包括:bot=mid+1、top=mid-1、bot-=1、top-=1,这些边界条件程序里面都避免了,具体怎么避免的这里就不再赘述了。
# -*- coding:utf-8 -*-
import math
class Solution:#这个时间复杂度为O(log以2为底的n)
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray)==0:
return 0
else:
bot=0
top=len(rotateArray)-1
while top>bot:
mid=int(math.ceil((bot+top)/2))#向上取整
if rotateArray[mid]<rotateArray[mid-1]:
return rotateArray[mid]
elif rotateArray[mid]>rotateArray[top]:
bot=mid+1
elif rotateArray[mid]<rotateArray[top]:
top=mid-1
else:
bot-=1
top-=1
return rotateArray[top]
方法二:遍历法:
# -*- coding:utf-8 -*-
class Solution:#这个时间复杂度为O(n)
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray)==0:
return 0
else:
for i in range(len(rotateArray)):
if i<len(rotateArray)-1:
if rotateArray[i+1]<rotateArray[i]:
return rotateArray[i+1]
else:
continue
else:
return rotateArray[i]
参考文献:
https://blog.youkuaiyun.com/weixin_40271182/article/details/84615481