剑指offer09 — 旋转数组中的最小数字
题目
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
思路
可以直接循环遍历找最小值,但是复杂度为o(n),需要利用题干中数组的递增信息,降低时间复杂度。
首先引入二分查找法:
def bSearch(array,target):
left=0
right=len(array)-1
while left <= right:
#mid = (left+right)//2 # //表示地板除,即先做除法(/),然后向下取整(floor)。至少有一方是float型时,结果为float型;两个数都是int型时,结果为int型。
mid = (left+right) >>1 #位运算,右移的操作就相当于除以2再取整,python中其实不是很重要,但是底层的话移位比较快。
if arrsy[mid]==target :
return mid
elif array[mid] <target:
left=mid+1
else:
right=mid-1
return None
复杂度为 l o g 2 n log_2n log2n,但凡遇到树形的,一半一半砍的,时间复杂度就是O( l o g 2 n log_2n log2n)
在寻找旋转数组的最小值时,也可以借用二分查找法的思想,那么如何判断向mid位置的左边还是右边进行查找呢 — > 如果right的值大于mid的值,则往左边找(说明中值往右仍为依次递增),否则往右边找(说明肯定有断崖,而断崖处则为最小值!)。
旋转数组中的最小值有什么样的特点?— 既小于前面又小于后面,本身就是依次递增的,必然会小于相邻的后边的值,即最小值的特点可以表述为小于左边相邻的值。
解
class Solution:
def minNumberInRotateArray(self, rotateArray):
# 如果数组大小为0,则返回0
if not rotateArray:
return 0
left =0
right=len(rotateArray-1)
while left <=right:
mid=(left+right)>>1
if rotateArray[mid] < rotateArray[mid-1]
return rotateArray[mid]
elif rotateArray[mid] < rotateArray[right]:
right=mid-1
else:
left=mid+1
return 0
类似题目网址:
https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/