《剑指offer》---寻找反转数组最小值

本文算法使用python3实现


1.题目描述:

  把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
  时间限制:3s;空间限制:32768K


2.思路描述:

  思路主要有以下两种:
  (1)暴力法:从头到尾遍历数组,找到最小值。该方法的时间复杂度为 $ O(n) $ ,当数组过大时,遍历时间较长,并且此方法并没有应用上“翻转数组”的特点。
  (2)折半查找法(二分查找):时间复杂度为 $ O(\log_2n) $ ,且可以利用本题“翻转”数组的特点。


  但是需要考虑两种情况!!!
  (1)存在重复数字,例如[1,0,1,1,1],使用暴力查找法,因为此时无法利用折半查找法里的一些判断条件。参考下图:
      1238724-20180516203421504-2045187619.jpg

  (2)不存在重复数字,例如[3,4,5,1,2],使用折半查找法,参考下图:
    (a)将指针 $ low $ 指向数组第0项, $ high $ 指向数组第n项。
    (b)指针 $ mid = (low+high)//2 $ ,若 $ array[mid]>=array[low] $ 且 $ array[mid]>array[high] $ ,此时移动指针 $ low=mid $ ;若 $ array[mid]<array[low] $ 且 $ array[mid]<=array[high] $ ,此时移动指针 $ high=mid $ 。重复(b)直到 $ low+1=high $ ,进入(c)
    (c)比较 $ array[low] $ 与 $ array[high] $ ,返回其中较小值。
      1238724-20180516203435138-1507171817.jpg


3.程序代码:

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        if len(rotateArray) == 0:
            return 0
        #array = sorted(rotateArray)
        #return array[0]
        low = 0
        high = len(rotateArray) - 1
        while low + 1 < high:
            mid = (low+high)//2
            # 当数组为:[1,0,1,1,1]时,只能使用暴力解法
            if rotateArray[mid] == rotateArray[low] and rotateArray[mid] == rotateArray[high]:
                return self.findmin(rotateArray)
            # 当数组正常时,例如:[3,4,5,1,2],使用二分查找法。
            # 注意等号:[3,0,1,1,1],[3,3,3,0,1]这两种情况
            if rotateArray[mid] >= rotateArray[low] and rotateArray[mid] > rotateArray[high]:
                low = mid
                continue
            if rotateArray[mid] < rotateArray[low] and rotateArray[mid] <= rotateArray[high]:
                high = mid
                continue
        if low + 1 >= high:
            return rotateArray[low] if rotateArray[low] < rotateArray[high] else rotateArray[high]

    def findmin(self,rotateArray):
        ''‘暴力解法’''
        min = rotateArray[0]
        for ele in rotateArray:
            if ele < min:
                min = ele
        return min

转载于:https://www.cnblogs.com/lliuye/p/9048020.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值