剖析LeetCode 84、Poj 2559和hdu 1506:柱状图中的最大矩形
2023-12-19 07:17:01
1. 问题概述:柱状图中的最大矩形
给定一个包含非负整数的柱状图,每个柱状图的宽度为1,我们需要找到柱状图中最大的矩形面积。
2. 循环方法:两次循环
最直观的解决方法是使用两次循环。外层循环遍历柱状图的每个柱子,内层循环遍历该柱子右侧的所有柱子,计算它们所能构成的矩形面积。如果某个柱子右侧没有其他柱子,那么它构成的矩形面积就等于其高度。
3. 循环方法:单调栈
为了优化循环方法,我们可以利用栈来记录柱子的高度。当我们遍历柱状图时,将每个柱子的高度入栈。如果当前柱子的高度大于栈顶元素的高度,那么栈顶元素构成的矩形面积就是最大矩形面积。将栈顶元素出栈,并以当前柱子为右边界计算矩形面积。
如果当前柱子的高度小于或等于栈顶元素的高度,那么我们将继续入栈,直到遇到一个高度较小的柱子。当遇到高度较小的柱子时,栈顶元素构成的矩形面积就是最大矩形面积。将栈顶元素出栈,并以当前柱子为右边界计算矩形面积。
4. 动态规划:一维数组
我们可以使用一维数组来存储每个柱子构成的最大矩形面积。假设数组dp[i]表示柱状图中第i个柱子构成的最大矩形面积,那么我们可以通过以下递推公式计算dp[i]:
dp[i] = max(dp[i], dp[i-1] + height[i])
其中height[i]表示第i个柱子的高度。这个递推公式表示第i个柱子构成的最大矩形面积要么是它自身构成的矩形面积,要么是它与左侧柱子构成的矩形面积加上它自身构成的矩形面积。
5. 代码示例
def largest_rectangle_area(heights):
stack = []
max_area = 0
for i, height in enumerate(heights):
while stack and height < heights[stack[-1]]:
h = heights[stack.pop()]
w = i if not stack else i - stack[-1] - 1
max_area = max(max_area, h * w)
stack.append(i)
while stack:
h = heights[stack.pop()]
w = len(heights) if not stack else len(heights) - stack[-1] - 1
max_area = max(max_area, h * w)
return max_area
def largest_rectangle_area_dp(heights):
n = len(heights)
dp = [0] * n
dp[0] = heights[0]
for i in range(1, n):
dp[i] = heights[i]
if heights[i] < heights[i-1]:
dp[i] = dp[i-1] + heights[i]
max_area = max(dp)
return max_area
6. 图示说明
图中给出了一个柱状图的例子,柱状图的高度分别为[2, 1, 5, 6, 2, 3]。使用循环方法可以计算出柱状图中最大的矩形面积为10,使用动态规划方法也可以计算出柱状图中最大的矩形面积为10。
7. 总结
在这篇文章中,我们介绍了LeetCode 84、Poj 2559和hdu 1506这三个题目的解题思路。我们从两个方向的循环方法开始,然后介绍了如何使用栈来优化算法。此外,我们还探讨了动态规划的解决方法,并提供了清晰的代码示例和详细的图示说明。希望这篇文章能够帮助您透彻理解这些问题的解决方案。