6、查找和排序——旋转数组的最小数字(python版)

题目描述

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


该数组中的重要数字特征为:非递减排序

首先,最简单的方式是

1、遍历算法

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        minNum = rotateArray[0]
        for i in range(0,len(rotateArray)):
        	minNum = minNum if minNum < rotateArray[i] else rotateArray[i]
        return minNum

时间复杂度为O(n)

然后,看能否进行优化。对于非递减的数列,可想到使用二分查找的思想进行数值查询。(二分查找:漫画:什么是二分查找

而输入的数组却是非递减排序数组翻转之后的数组。
例如:
1 2 3 4 5 6 7 8 9==》 6 7 8 9 5 1 2 3 4
6 7 8 9 ==》8 9 6 7

对于反转后的情况讨论,
当为奇数位数组时,右半侧一定比中位数小,左右半侧均为非递减且右半侧均小于左半侧,因此左右半侧中的前一个数一定会比后一个数小;
当为偶数位数组时,右半侧比左半侧小,左右半侧均为非递减且右半侧均小于左半侧,因此左右半侧中的前一个数一定会比后一个数小。

根据这个特性,发现当找到的某个数比它的前一个数小时,说明是找到了翻转的分界点,且该数为原非递减数列的第一位数,可以确定该数一定为最小数。若不满足上述条件且该数比它的最右端数小,说明该数为右半侧数,由于为非递减排序最小值在该数左侧;反之,则说明该数为左半侧书,最小值应为应为数列的右半侧在它的右侧。

2、二分查找搜索

class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        # 数组为空时返回0
        if not rotateArray:
            return 0
        
        low = 0
        high = len(rotateArray)-1
        while low <= high:
            mid = (low + high) // 2   # 除以2时向下取值
            if rotateArray[mid] < rotateArray[mid-1]:
                return rotateArray[mid]
            elif rotateArray[mid] < rotateArray[high]:
                high = mid - 1
            else:
                low = mid + 1
                
        return 0

时间复杂度为O(logn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辰阳星宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值