返回

盛最多水的容器的极限挑战:剖析 LeetCode 11 的巧妙解法

前端

剖析 LeetCode 11:盛最多水的容器的极致解法

导言:盛水容器的本质

LeetCode 11 盛水容器的问题本质上是一个几何问题,要求在给定一组垂直线段的高度下,求出可以盛放最多水的容器的体积。直观地看,这个体积是由两条线段之间的宽度和较短线段的高度决定的。

动态规划解法:全面求解

动态规划是一种自顶向下的解题方法,通过存储子问题的解来避免重复计算。在这个问题中,我们可以定义一个二维表格 dp[i][j],其中 dp[i][j] 表示以 ij 为左右边界构成的容器能盛放的最大水量。

动态规划方程:

dp[i][j] = max{dp[i+1][j], dp[i][j-1], min(height[i], height[j]) * (j - i)}

贪心算法解法:双指针夹击

贪心算法是一种自底向上的解题方法,每次选择局部最优解,逐步逼近全局最优解。在这个问题中,我们可以使用双指针从容器的两端向中间移动,每次移动较短线段的指针。

贪心算法步骤:

  1. 初始化两个指针 leftright 分别指向容器的左端和右端。
  2. 循环直到 left 指针大于或等于 right 指针。
  3. 计算当前容器的体积 area = min(height[left], height[right]) * (right - left)
  4. 如果 height[left] 小于 height[right], 将 left 指针向右移动,否则将 right 指针向左移动。
  5. 更新最大体积。

比较分析:

动态规划算法的时间复杂度为 O(n^2),而贪心算法的时间复杂度仅为 O(n),因此贪心算法在效率上远胜于动态规划算法。然而,动态规划算法可以提供更全面的解,而贪心算法可能找到局部最优解而非全局最优解。

代码示例:

动态规划算法 Python 代码:

def maxArea(height):
    n = len(height)
    dp = [[0] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = 0
    for i in range(n-1):
        for j in range(i+1, n):
            dp[i][j] = max(dp[i+1][j], dp[i][j-1], min(height[i], height[j]) * (j - i))
    return max(max(row) for row in dp)

贪心算法 Python 代码:

def maxArea(height):
    left, right = 0, len(height)-1
    max_area = 0
    while left < right:
        max_area = max(max_area, min(height[left], height[right]) * (right - left))
        if height[left] < height[right]:
            left += 1
        else:
            right -= 1
    return max_area

总结

LeetCode 11 盛水容器的问题看似简单,但其背后蕴含着深刻的算法思想。通过动态规划和贪心算法的对比分析,我们了解到不同算法在效率和全面性方面的权衡取舍。理解这些算法背后的原理对于解决更复杂的编程问题至关重要。