6.旋转数组的最小数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
记录
方法1:
直接遍历,比较得出最小。
但是这个办法复杂的比较高,也没有体现题目的用意。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
else:
for i in range(len(rotateArray) - 1):
if(rotateArray[i+1] <rotateArray[i]):
minres = rotateArray[i+1]
return minres
方法2:二分法
二分仅限于数组没有相同元素的时候,如果有相同元素只能遍历数组。(题目没有说明“递增”是指“非递减”还是“严格递增”)。
给定的是翻转后的数组rotateArray,又原数组是非递减排序的,如{3,4,5,1,2}为{1,2,3,4,5}的翻转.
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
lenArr = len(rotateArray)
left, right = 0, lenArr-1
mid = left #如果没反转,直接返回最左了
#最左小于最右,说明翻转了
while rotateArray[left] >= rotateArray[right]:
#只有两个元素,且根据循环左边大于右边,则最小值为右边的
if right - left == 1:
return rotateArray[right]
#多个元素
mid = (left + right)//2 #中间元素
#特殊情况:有重复元素使用遍历法
if rotateArray[left] == rotateArray[mid] and rotateArray[mid] == rotateArray[right]:
res = rotateArray[left]
for i in range(left, right+1):
if res > rotateArray[i]:
res = rotateArray[i]
return res
#左指针的元素小于中间元素,[3,4,5,1,2],左指针移动到中间元素[5,1,2]
if rotateArray[mid] >= rotateArray[left]:
left = mid
#[5,1,2]->[5,1],满足只有两个元素
elif rotateArray[mid] <= rotateArray[right]:
right = mid
return rotateArray[mid]
方法3:递归
和方法2的思想差不多。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
if not rotateArray:
return 0
if len(rotateArray)==2:
return rotateArray[1]
mid = int(len(rotateArray)/2)
if rotateArray[mid] > rotateArray[0]:
return self.minNumberInRotateArray(rotateArray[mid:])
elif rotateArray[mid] < rotateArray[0]:
return self.minNumberInRotateArray(rotateArray[:mid+1])
else:
#有相同元素只能遍历数组
for i in range(1,len(rotateArray)):
if rotateArray[i] < rotateArray[0]:
return rotateArray[i]
return rotateArray[0]