返回

LeetCode 第 154 题:寻找旋转排序数组中的最小值 II

见解分享

如何找到旋转排序数组中的最小值,即使有重复元素:一个逐步指南

简介

旋转排序数组是一种按升序排列的数组,被旋转了一次或多次,形成了一个“环”。当数组中存在重复元素时,找到最小值会变得更具挑战性。本文将深入探讨如何使用二分查找算法高效地解决这个棘手的问题。

二分查找算法

二分查找是一种通过将搜索空间一分为二来工作的搜索算法。对于旋转排序数组,我们需要考虑重复元素的影响。

分步指南

  1. 初始化变量:

    • 设置数组的起始索引为 left = 0
    • 设置数组的结束索引为 right = n-1,其中 n 是数组的长度。
    • 将最小值设为正无穷大,即 min = float('inf')
  2. 二分查找循环:

    • 只要 left <= right,执行以下步骤:
      • 计算中间索引 mid = (left + right) // 2
      • 如果 nums[mid] 小于 min,则更新 minnums[mid]
      • 如果 nums[mid] 等于 nums[right],说明右半部分存在重复元素,将 right 减 1。
      • 如果 nums[mid] 小于 nums[right],说明最小值在右半部分,将 left 设为 mid + 1
      • 如果 nums[mid] 大于 nums[right],说明最小值在左半部分,将 right 设为 mid
  3. 返回最小值:

    • 循环结束后,返回 min

示例

考虑以下旋转排序数组:

nums = [3,4,5,1,2]

按照上述步骤进行二分查找:

  1. 初始化 left = 0right = 4min = float('inf')
  2. 计算 mid = 2nums[mid] = 5,不更新 minnums[mid] 等于 nums[right],将 right 减 1,现在 right = 3
  3. 计算 mid = 2nums[mid] = 5,不更新 minnums[mid] 等于 nums[right],将 right 减 1,现在 right = 2
  4. 计算 mid = 1nums[mid] = 4,不更新 minnums[mid] 小于 nums[right],将 left 设为 mid + 1,现在 left = 2
  5. 计算 mid = 2nums[mid] = 5,不更新 minnums[mid] 等于 nums[right],将 right 减 1,现在 right = 1
  6. 计算 mid = 1nums[mid] = 4,不更新 minnums[mid] 小于 nums[right],将 left 设为 mid + 1,现在 left = 2
  7. 计算 mid = 2nums[mid] = 5,不更新 minnums[mid] 等于 nums[right],将 right 减 1,现在 right = 0
  8. 计算 mid = 0nums[mid] = 3,更新 min 为 3。
  9. 返回 min = 3

代码实现

def findMin(nums):
    left = 0
    right = len(nums) - 1
    min = float('inf')
    
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] < min:
            min = nums[mid]
        if nums[mid] == nums[right]:
            right -= 1
        elif nums[mid] < nums[right]:
            left = mid + 1
        else:
            right = mid
            
    return min

结论

使用二分查找算法可以高效地解决寻找旋转排序数组中最小值的问题,即使存在重复元素。该算法通过考虑重复元素的影响并使用适当的比较,可以收窄搜索空间并找到最小值。理解旋转排序数组以及解决类似问题对于实际应用至关重要。

常见问题解答

  1. 什么是旋转排序数组?

旋转排序数组是一种按升序排列的数组,被旋转了一次或多次,形成了一个“环”。

  1. 当数组中存在重复元素时,寻找最小值有什么困难?

重复元素使得难以确定哪个半部分包含最小值。

  1. 二分查找算法如何解决这个问题?

二分查找算法通过考虑重复元素的影响并使用适当的比较,可以收窄搜索空间。

  1. 代码示例中的 min 变量的作用是什么?

min 变量存储当前找到的最小值。

  1. 该算法的时间复杂度是多少?

该算法的时间复杂度为 O(log n),其中 n 是数组的长度。