返回
盛最多水的容器的极限挑战:剖析 LeetCode 11 的巧妙解法
前端
2023-09-22 10:37:10
剖析 LeetCode 11:盛最多水的容器的极致解法
导言:盛水容器的本质
LeetCode 11 盛水容器的问题本质上是一个几何问题,要求在给定一组垂直线段的高度下,求出可以盛放最多水的容器的体积。直观地看,这个体积是由两条线段之间的宽度和较短线段的高度决定的。
动态规划解法:全面求解
动态规划是一种自顶向下的解题方法,通过存储子问题的解来避免重复计算。在这个问题中,我们可以定义一个二维表格 dp[i][j]
,其中 dp[i][j]
表示以 i
和 j
为左右边界构成的容器能盛放的最大水量。
动态规划方程:
dp[i][j] = max{dp[i+1][j], dp[i][j-1], min(height[i], height[j]) * (j - i)}
贪心算法解法:双指针夹击
贪心算法是一种自底向上的解题方法,每次选择局部最优解,逐步逼近全局最优解。在这个问题中,我们可以使用双指针从容器的两端向中间移动,每次移动较短线段的指针。
贪心算法步骤:
- 初始化两个指针
left
和right
分别指向容器的左端和右端。 - 循环直到
left
指针大于或等于right
指针。 - 计算当前容器的体积
area = min(height[left], height[right]) * (right - left)
。 - 如果
height[left]
小于height[right]
, 将left
指针向右移动,否则将right
指针向左移动。 - 更新最大体积。
比较分析:
动态规划算法的时间复杂度为 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 盛水容器的问题看似简单,但其背后蕴含着深刻的算法思想。通过动态规划和贪心算法的对比分析,我们了解到不同算法在效率和全面性方面的权衡取舍。理解这些算法背后的原理对于解决更复杂的编程问题至关重要。