线性枚举(3)

最值算法_153

题目

来源:153. 寻找旋转排序数组中的最小值
难度:中等
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [ a [ 0 ] , a [ 1 ] , a [ 2 ] , . . . , a [ n − 1 ] ] [a[0], a[1], a[2], ..., a[n-1]] [a[0],a[1],a[2],...,a[n1]]旋转一次的结果为数组
[ a [ n − 1 ] , a [ 0 ] , a [ 1 ] , a [ 2 ] , . . . , a [ n − 2 ] ] [a[n-1], a[0], a[1], a[2], ..., a[n-2]] [a[n1],a[0],a[1],a[2],...,a[n2]]

给你一个元素值互不相同的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的最小元素

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums中所有整数互不相同
nums原先是一个升序排序的数组,并进行了1至n次的旋转

解题思路

  • 时间复杂度为O(logn),首先想到二分法,即需要每次要从数组中选出k分之一(二分法k=2)。
  • 数组进行了旋转,打破了原有的升序性,但数组还是部分升序的,重点就是要找出破坏升序的地方,就能找到最小值。
  • 通过三个数来分割数组,数组的首元素、末元素和最中间元素。
    • 如果首元素 < 中间元素 < 末元素,说明数组是升序的最小值就是首元素。
    • 如果首元素 > 中间元素,说明最小值在前半部分,注意前半部分也应该包含中间元素。
    • 如果中间元素 > 末元素,说明最小值在后半部分。
  • 重复上面三步直到数组长度为2,最小值即为nums[1]

代码

class Solution:
    def findMin(self, nums: List[int]) -> int:
        while(1):
            if nums[0] > nums[int(len(nums)/2)]:
                nums = nums[:int(len(nums)/2)+1]
            elif nums[int(len(nums)/2)] > nums[-1]:
                nums = nums[int(len(nums)/2):]
            else:
                numMin = nums[0]
                break
            if len(nums)==2:
                numMin = nums[1]
                break
        return numMin
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值