【LeetCode 中等题】76-寻找旋转排序数组中的最小值

题目描述:假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [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

解法1。因为是旋转数组,所以2子数组内部是有序的,用左右双指针法,3个点:

  • while循环条件改为nums[left] > nums[right],因为我们始终要找的最小元素最可能在两子串连接处,所以如果左元素小于右元素说明该子数组有序,应该退出循环
  • 如果mid、left、right这3个元素相等,可能是11101等情况,不好判断是往左还是往右,这种情况就顺序找最小值
  • 如果right-left == 1,就直接返回right指向的元素
class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        left = 0
        right = len(nums)-1
        mid = 0
        while nums[left] > nums[right]:    # 因为是旋转,2部分子串内部依然有序,所以如果左元素<右元素便认为该子串有序,可以退出
            mid = (left+right)//2
            if right -left == 1:
                return nums[right]
            if nums[mid] == nums[left] and nums[mid] == nums[right]:
                return self.inOrder(nums, left, mid)
            
            elif nums[mid] >= nums[left]:
                left = mid
            elif nums[mid] <= nums[right]:
                right = mid
        return nums[mid]
    def inOrder(self, nums, le, ri):
        res = nums[le]
        for i in range(le+1, ri+1):
            res = min(res, nums[i])
        return res

解法2。正常左右指针的方法。

class Solution(object):
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        left = 0
        right = len(nums)-1
        mid = 0
        while left < right:    # 注意这个地方不能加=,这样就死循环了
            mid = (left+right)//2
            if nums[mid] > nums[right]:
                left = mid+1
            else:
                right = mid
        return nums[left]

猜你喜欢

转载自blog.csdn.net/weixin_41011942/article/details/86465691