目录
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。一、Python:
1.1 直接使用min函数解题,但不足以拿到offer
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if rotateArray is None or len(rotateArray)==0:
return 0
else:
return min(rotateArray)
也可以写成一行代码更pythonic:
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
return 0 if rotateArray is None or len(rotateArray)==0 else min(rotateArray)
1.2 思想:旋转前后数组的最小值肯定是不变的。我们先假设数组中一个元素为最小值,然后遍历该数组,如果遍历到的元素比之前假定的最小值要小,那么替换,如果大,跳过。这个马马虎虎,时间复杂度O(n),有点高了。。。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray) == 0 or rotateArray is None:
return 0
else:
minNumber = rotateArray[0]
for i in range(1, len(rotateArray)):
if rotateArray[i] < minNumber:
minNumber = rotateArray[i]
return minNumber
1.3 该解法思路参考二分查找,时间复杂度O(lgn)。整体算法思路整理如下:
二分需要两个指针,一个指向数组开始,另一个指向数组结尾。接下来二分,查看该位置的数组元素与左指针指向的元素比大小,分三种情况讨论:
mid = left + (right-left)//2
1) array[mid]>array[left]:
[3,4,4,5,6,1,1,2,3]
left ,right = 0, 8
mid = 4
说明最小数在[mid, right]里,left = mid,再分,left, mid, right = 4, 6, 8。array[mid]<array[left], right = mid;直到[6,1]时mid= right, return array[mid]。
2) array[mid]<array[left]:
[3,4,4,5,1,1,2,3]
left ,right = 0, 7
mid = 4
说明[left, mid]里一定会有转折点,而转折点就是最小数,最小数在[left, mid]里,mid = right。再分,array[2]>array[4],直至[5,1],mid=right,return array[mid]。
3) array[mid]=array[left]:
[3,3,3,3,3,2,2,2],类似于这种,两种方法:
3.1 遍历数组
3.2 不改变原有顺序去重后按1)2)做
Ref:
1、https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba
2、