面试题11:旋转数组的最小数字

剑指 Offer 11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。  

示例 1:

输入:[3,4,5,1,2]
输出:1
示例 2:

输入:[2,2,2,0,1]
输出:0

这道题,表面上看起来很简单,直接遍历就可以得出最小值,时间复杂度为O(n)也刚刚好感觉不是很高,面试官就会提示你,是不是有更低的时间复杂度,因为如果他给出的是一个乱序的和旋转数组你给出的时间复杂度都是O(n),面试官为什么要费劲巴力的整一个旋转数组的新概念出来,所以时间复杂度肯定会小于O(n)

这道题的核心思想就在于二分法,之前文章有提到,如果是在一个有序数组中查找,八成是用的二分法。这道题也相似,数组本身是有序的,二分法思想查找最小值比如题中给出的这个示例[3,4,5,1,2],拿到首尾值和中间值,比如首为3,中间值为5,那3和5之间肯定是递增的,这时最小值肯定在5和2之间,此时再次二分,首为5尾为1,这时5和1之间的距离为1,已经无法二分,也就是说最小值就在5和1之间,返回最小值就好。

但是,几个特殊例子这个就要判断特殊情况了

[0]

[1,2,3]

[1,1]

[2,2,2,0,1]

碰到只有一个元素的,直接返回n[0],碰到全递增的,也就是n[0]<n[-1]的,直接返回n[0]

碰到第三种全相等的,直接返回n[0]

碰到最后一种的,只能遍历查找

综上,就要多写几行特殊情况判断了

class Solution(object):
    def minArray(self, numbers):
        """
        :type numbers: List[int]
        :rtype: int
        """
        if numbers[0] < numbers[-1] or len(numbers) == 1:
            return numbers[0]
        low = 0
        pre = len(numbers) - 1
        middle = int((low + pre)/2)
        while(low >= pre):
            if pre - low == 1:
                return min(numbers[pre],numbers[low])
            if numbers[low] < numbers[middle]:
                low = middle
                continue
            elif numbers[low] > numbers[middle]:
                pre = middle
                continue
        for i in range(len(numbers)-1):
            if numbers[i] > numbers[i+1]:
                return numbers[i+1]
        return numbers[0]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值