题目描述:
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
解答如下:环境:python 2.7.3
解法一:暴力解法 时间复杂的O(n)
旋转数组的最小值必然比前面它所在位置的前一个元素的值小,可以参考上图,i往右移动,j为i右边的元素,当出现j处元素的值小于i处的值时,可以认为j处是最小元素。当没有找到符合情况的元素时,第一个元素就是最小的。
当然本题是非递增数组,当出现所有元素的值相同时,第一个元素就是最小的元素。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
#非二分法时间复杂度O(n)
length = len(rotateArray)
if(length <= 0):
return 0
for i in range(0, length-1):
j = i + 1
if rotateArray[i] > rotateArray[j]:
return rotateArray[j]
return rotateArray[0]
解法二:二分查找法 时间复杂度O(logn)
解法二是通过二分查找法来判断中间元素是不是处在被旋转的那些元素之中,如果一个元素是被旋转的元素之一,那么它一定小于最右边的right元素,如果一个元素不是被旋转的元素之一,那么它一定大于最右边的right元素,例子一中middle元素5不在被旋转的元素之中,因为它大于2,那么可以知道最小值一定在其右边,例子二中middle=2<4所以最小值一定在其左边。当发现middle处的值小于它前面的值时,midlle处就是最小值,当然如果数组全部相等,最小值就是第一个值。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
if not rotateArray:
return None
left = 0
right = len(rotateArray) - 1
while left <= right:
mid = (left + right) >> 1 #相当于(left + right)/2
if rotateArray[mid] < rotateArray[mid-1]:
return rotateArray[mid]
elif rotateArray[mid] < rotateArray[right]:
right = mid - 1
else:
left = mid + 1
return rotateArray[0]