153. Find Minimum in Rotated Sorted Array

本文介绍了一种在已排序并旋转的数组中找到最小元素的方法。利用数组旋转后的特性,通过二分查找优化搜索过程,避免了遍历整个数组。文章提供了Python实现,并对比了不同方法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.
  • python内置函数min(nums),显然这么解不是本题原意
  • 有次序的列表旋转特性:第一个小于尾字符的字符即为旋转点(二分用不到,遍历可用)
  • 旋转点比左/右边界都小(二分)
  • 二分应该优于遍历查找

    solution

无其他库版本

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        right = len(nums)-1
        left = 0 
        while left < right:
            if nums[left] <= nums[right]:
                return nums[left]
            mid = (left + right)/2
            if nums[mid] > nums[right]:
                left = mid + 1
            else:
                right = mid
        return nums[left]
        
            if nums[left] <= nums[right]:
                return nums[left]

其中这段不是标准的二分,逻辑比较难理解,可以提高执行效率

  1. 如果是空元素,单元素,无旋转序列直接给出结果
  2. 每次切分后,根据特性做一个判断,如果left已经到达旋转点,则返回

如何确认return时left元素刚好位于旋转点,而不是旋转点后?

此前left右移,left = mid + 1
此时left左边相邻元素为mid元素,已经通过游标右移判断nums[mid] > nums[right],left即为旋转点

nums[mid] > nums[right]

nums[left] = nums[mid+1] <= nums[right]

此前right左移,right = mid ,左移前提nums[mid] <= nums[right], 由于旋转特性right左移范围不会越过旋转点,(其实left右移同样不会越过)

旋转点左边的值肯定大于右边的值,这一特性可以推导出,right左移不会越过旋转点(right =mid,只有mid<= right的时候才可左移),left右移同样不会(left = mid +1, 只有在mid>right的时候才可右移)

discuss solution

class Solution:
    def findMin(self, nums):
        self.__getitem__ = lambda i: nums[i] <= nums[-1]
        return nums[bisect.bisect(self, False, 0, len(nums))]

炫技写法

getitem 鸭子类型,列表特性

此时self[i] = True/False

此时solution instance 具有列表部分特性 , 类似的格式为[False,False,False,True,True,True]

len(nums) 没用默认参数是因为此时,solution instance 还没有 len 方法

https://docs.python.org/2/library/bisect.html

bisect.bisect(a, x, lo=0, hi=len(a))
Similar to bisect_left(), but returns an insertion point which comes after (to the right of) any existing entries of x in a.

The returned insertion point i partitions the array a into two halves so that all(val <= x for val in a[lo:i]) for the left side and all(val > x for val in a[i:hi]) for the right side.

转载于:https://www.cnblogs.com/salmd/p/5914311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值