返回

解构 LeetCode 11:盛最多水的容器——揭秘盛水量最大值背后的算法原理

前端

问题解析:从容器到矩形

LeetCode 11题本质上是一个几何问题,它将容器盛水的过程抽象成矩形面积计算。我们只需找到两条垂直线段,使它们围成的矩形面积最大即可。

算法选择:动态规划 VS 双指针

解决该问题的算法有多种,但最常用的方法是动态规划和双指针法。

  • 动态规划: 动态规划算法通过构建一个动态规划表,以记录每一步计算的结果,从而实现最优解的求取。这种方法虽然简单易懂,但时间复杂度较高,为 O(n^2)。

  • 双指针法: 双指针法是一种更有效的方法,它通过两个指针分别从容器的两端向中间移动,并在移动过程中计算出当前盛水量。这种方法的时间复杂度仅为 O(n),大大优于动态规划法。

双指针法:精妙且高效的解法

双指针法是一种极其巧妙的算法,它通过两个指针同时从容器的两端向中间移动,并在移动过程中不断更新盛水量最大值。

  1. 初始化: 将两个指针分别指向容器两端,即指向第一个和最后一个垂直线段。

  2. 移动指针: 同时将两个指针向中间移动,即分别向右和向左移动一个单位。

  3. 计算盛水量: 在移动指针的同时,计算当前两个指针围成的矩形的面积,并将其与当前盛水量最大值进行比较。如果当前面积较大,则更新盛水量最大值。

  4. 重复步骤 2 和 3: 重复步骤 2 和 3,直到两个指针相遇。

代码实现:Python 版

def max_area(height):
  """
  计算盛最多水的矩形面积。

  参数:
    height: 一个包含 n 个非负整数的列表,表示容器中垂直线段的高度。

  返回:
    盛最多水的矩形面积。
  """

  # 初始化两个指针
  left, right = 0, len(height) - 1

  # 初始化盛水量最大值
  max_area = 0

  # 循环移动指针
  while left < right:
    # 计算当前盛水量
    current_area = min(height[left], height[right]) * (right - left)

    # 更新盛水量最大值
    max_area = max(max_area, current_area)

    # 移动指针
    if height[left] < height[right]:
      left += 1
    else:
      right -= 1

  # 返回盛水量最大值
  return max_area


# 测试用例
height = [1, 8, 6, 2, 5, 4, 8, 3, 7]
print(max_area(height))  # 输出:49

总结

LeetCode 11题是一个经典的算法问题,它不仅考验我们的算法能力,也考验我们对几何问题的理解。通过对问题进行深入分析,我们找到了两种求解方法:动态规划法和双指针法。其中,双指针法以其高效和简洁性脱颖而出,成为解决该问题的最佳选择。希望这篇博文能帮助你更好地理解 LeetCode 11题的解题思路和算法实现。