问题描述
小S最近在分析一个数组 h1,h2,...,hNh1,h2,...,hN,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk 个相邻元素时,如何计算它们所能形成的最大矩形面积。
对于 kk 个相邻的元素,我们定义其矩形的最大面积为:
R(k)=k×min(h[i],h[i+1],...,h[i+k−1])R(k)=k×min(h[i],h[i+1],...,h[i+k−1])
即,R(k)R(k) 的值为这 kk 个相邻元素中的最小值乘以 kk。现在,小S希望你能帮他找出对于任意 kk,R(k)R(k) 的最大值。
测试样例
样例1:
输入:
n = 5, array = [1, 2, 3, 4, 5]
输出:9
样例2:
输入:
n = 6, array = [5, 4, 3, 2, 1, 6]
输出:9
样例3:
输入:
n = 4, array = [4, 4, 4, 4]
输出:16
题目解析
思路
这道题的核心是通过滑动窗口和单调栈求解最大矩形面积:
-
定义矩形面积:选取任意 kkk 个相邻元素,矩形面积 R(k)R(k)R(k) 是这些元素的最小值乘以 kkk。
-
优化计算过程:如果直接对每个 kkk 计算最小值,会导致复杂度为 O(n2)O(n^2)O(n2)。因此,引入单调栈优化到 O(n)O(n)O(n)。
-
单调栈思想:
- 左右扩展每个元素,找到第一个小于它的位置,从而确定以该元素为高度的矩形宽度。
- 使用单调递增栈快速查找左右边界。
图解
假设数组为 [2,1,5,6,2,3][2, 1, 5, 6, 2, 3][2,1,5,6,2,3],我们以高度 h[i]h[i]h[i] 为中心计算影响范围:
-
构建
left数组:每个柱子左侧第一个小于它的下标。 -
构建
right数组:每个柱子右侧第一个小于它的下标。 -
计算矩形面积:
- 宽度为 right[i]−left[i]−1\text{right}[i] - \text{left}[i] - 1right[i]−left[i]−1,高度为 h[i]h[i]h[i]。
- 更新最大值。
代码详解
代码分为三部分:
-
初始化:创建
left和right数组,辅助栈stack。 -
构建边界:
- 遍历数组,利用单调递增栈分别计算左右边界。
-
计算最大矩形面积:
- 遍历每个元素,利用宽度和高度计算面积并更新最大值。
代码如下:
python
复制代码
def solution(n, array):
max_area = 0
left = [0] * n
right = [0] * n
# 构建左边界
stack = []
for i in range(n):
while stack and array[stack[-1]] >= array[i]:
stack.pop()
left[i] = stack[-1] if stack else -1
stack.append(i)
# 构建右边界
stack = []
for i in range(n - 1, -1, -1):
while stack and array[stack[-1]] >= array[i]:
stack.pop()
right[i] = stack[-1] if stack else n
stack.append(i)
# 计算最大矩形面积
for i in range(n):
width = right[i] - left[i] - 1
max_area = max(max_area, width * array[i])
return max_area
知识总结
新知识点
-
单调栈:
- 用于快速求解数组中每个元素的左右边界。
- 适用于「第一个小于某值」或「第一个大于某值」的问题。
-
滑动窗口优化:
- 简化暴力计算中的重复操作,减少时间复杂度。
-
最大矩形问题模型化:
- 将矩形问题转化为柱状图问题,利用分而治之思想。
理解与建议
-
对于入门同学:
- 从基础问题入手,理解单调栈的逻辑(如求解下一个更大元素)。
- 逐步尝试应用到实际场景,如最大矩形面积或直方图问题。
学习计划
刷题计划
-
每天三题:
- 选择简单、中等、困难各一题。
- 确保时间集中在 1-2 小时内完成。
-
错题本记录:
- 将错误的思路和正确解法进行对比。
- 重点记录不熟悉的算法(如单调栈、动态规划等)。
利用错题进行针对性学习
-
归类错题:
- 按题型(栈、队列、二分等)分类,明确薄弱环节。
-
针对性练习:
- 通过 MarsCode AI 提供的类似题目进行强化训练。
工具运用
结合 MarsCode AI 的学习方法
-
实时代码评测:
- 利用 MarsCode AI 的代码评测功能,快速验证代码的正确性。
-
错题推荐:
- MarsCode AI 根据错题记录自动推荐相似题目,帮助巩固知识点。
-
题目解析和提示:
- 使用 MarsCode AI 的解析功能,了解复杂问题的拆解过程。
学习资源结合
- 与经典算法书籍结合,如《算法导论》。
- 结合可视化工具(如 Python Tutor)动态演示栈操作过程。
实用建议
- 多与 AI 互动,快速解决疑惑。
- 定期复盘,总结常见思路和模式。
- 参与算法竞赛或社区讨论,获取更多思维拓展的机会。