• leetcode 旋转数组的最小数字【二分】


    假设按照升序排序的数组在预先未知的某个点上进行了旋转。

    ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

    请找出其中最小的元素。

    你可以假设数组中不存在重复元素。

    示例 1:

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

    输入: [4,5,6,7,0,1,2]
    输出: 0

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路: 首先这个数组在局部上仍是有序的,只是被分为了前后两个有序的部分。

    我们可以知道,当一个有序数组被旋转之后,前半部分和后半部分分别有序,并且前半部分的值必定大于后半部分,并且题目所求最小数字位于前半部分与后半部分的交界处。

    如何定位最小数字的位置,我们使用二分时,会选出一个Mid值进行一定条件的比较,以判断向某个方向缩小搜索范围。

    此时我们有一个位于中间的数字mid,可以将其与最左边的数进行比较,当发现大于最左边的数时,说明当前mid的值位于有序数组的前半部分,这是显而易见的,因为若该mid位置的值小于最左边的值,那么明显是后半部分的值,因为前半部分的所有值都大于等于后半部分的值。由此定位到我们正搜索的位置,并且我们知道,最小值位于右半部分的第一个值,,位于左半部分的最后一个值之后。

    通过比较左右边界的大小的信息,我们容易得出目标值位于左边还是右边,当Mid大于左边界的值时,向右搜索,尽量使搜索范围靠近右半部分。

    当mid的值小于左边界时,该值一定位于右半部分,此时可能当前值以及当前值的左边存在目标值。于是向左搜索。

    在二分的过程中,我们可以多次判断当前值与前后两值的关系,当前一个值大于当前值,或后一个值小于当前值时【不满足单调递增的性质】说明已经找到了两部分的边界,可以直接返回结果

    class Solution:
        def findMin(self, nums: List[int]) -> int:
            if nums[0]<=nums[-1]:
                return nums[0]
            l=0
            r=len(nums)-1
            while l<=r:
                mid=(l+r)//2
                if nums[mid]>nums[mid+1]:
                    return nums[mid+1]
                if nums[mid]<nums[mid-1]:
                    return nums[mid]
                if nums[mid]>nums[l] :
                    l=mid+1
                else:r=mid-1
    
  • 相关阅读:
    [2013-08-19] nohup的使用
    HttpParser 相关链接文章
    CKEditor禁用浏览服务器的功能
    (转载)MySQL删除所有表的外键约束、禁用外键约束
    js Object扩展自定义方法,jQuery抛出 Uncaught TypeError: matchExpr[type].exec is not a function
    Javascript 占位符替换
    Springboot 抛出Failed to determine a suitable driver class异常原因
    jpa CriteriaQueryNo explicit selection and an implicit one could not be determined
    Spring ModelAttribute注解失效原因
    Spring Data Jpa 更新操作
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11794297.html
Copyright © 2020-2023  润新知