美文网首页
153. 旋转数组最小值

153. 旋转数组最小值

作者: 霍尔元件 | 来源:发表于2019-06-03 22:04 被阅读0次

    刷题内容

    原题连接

    内容描述

    Suppose an array sorted in ascending order 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.
    
    Example 1:
    
    Input: [3,4,5,1,2] 
    Output: 1
    Example 2:
    
    Input: [4,5,6,7,0,1,2]
    Output: 0
    

    思路一: 唯一下降子序列

    class Solution:
        def findMin(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            if len(nums) == 1:
                return nums[0]
            for i in range(1, len(nums)):
                if nums[i] < nums[i - 1]:
                    return nums[i]
            return nums[0]
    

    思路二: 证明法

    带证明的解法
    left < right ==> mid < right 因为mid可能等于left但是绝对不可能等于right
    nums[mid] != nums[right]
    所以可以比较nums[mid] 和 nums[right] 并且只有两种情况

    • nums[mid] > nums[right] 说明最小值在右半段
      可以推出nums[mid]不可能是最小值 所以可以放心的让 left = mid + 1
    • nums[mid] < nums[right] 说明最小值在左半端 不能让right = mid - 1
      因为mid可能是最小值 只能够是 right = mid 那么这样会不会使得区间不收缩 陷入死循环呢 答案是不会 因为 mid < right 区间必然收缩
    • 当while的判断条件不再满足 left == right 找到最优解
    class Solution:
        def findMin(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            left, right = 0, len(nums) - 1
            while left < right:
                mid = (left + right) // 2
                if nums[mid] > nums[right]:
                    left = mid + 1
                else:
                    right = mid
            return nums[left]
    

    思路三: 混合

    class Solution(object):
        def findMin(self, nums):
            """
            :type nums: List[int]
            :rtype: int
            """
            l, r = 0, len(nums) - 1
            while l <= r:
                mid = (l + r) // 2
                if nums[mid] < nums[mid - 1]:  # 数组中唯一一个逆序 序列 找到之后直接返回
                    return nums[mid]
    
                elif nums[mid] < nums[l]:  # mid 位于右段 target位于左段 因为确定mid位置不会是最小值 所以可以放心地令 right = mid - 1
                    r = mid - 1
                elif nums[mid] > nums[r]:  # mid 位于左段 target位于右段 因为nums[mid]不可能是最小值
                    l = mid + 1
                else:  # 处理只有一个元素的情况 [1]
                    return nums[l]
    
    

    相关文章

      网友评论

          本文标题:153. 旋转数组最小值

          本文链接:https://www.haomeiwen.com/subject/tkohxctx.html