问题描述
测试样例
样例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
-
其实,这一题就是找数组的最大相同部分,也就是说尽可能的找到各个柱子凑在一起,找出最大的共有部分。
-
当然,如果其中一个柱子很高,而其他柱子很矮,那也有可能最大面积就取那个很高的柱子
-
很显然,这一题跟柱子的高度以及所有柱子的共有部分有关。典型的单调栈结构
-
既然是单调栈,那就假设没根柱子的高度是最大值,然后找左侧、右侧离当前柱子的最近距离。中间就是共有性质。
cppCopy Code
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int solution(int n, int array[]) {
// 创建一个单调递增的栈
stack<int> s;
int maxArea = 0;
// 遍历所有的柱子
for (int i = 0; i < n; ++i) {
// 如果当前柱子比栈顶柱子低,则计算栈顶柱子的矩形面积
while (!s.empty() && array[s.top()] > array[i]) {
int h = array[s.top()];
s.pop();
int w = s.empty() ? i : i - s.top() - 1;
maxArea = max(maxArea, h * w);
}
// 将当前柱子的索引入栈
s.push(i);
}
// 处理栈中剩余的柱子
while (!s.empty()) {
int h = array[s.top()];
s.pop();
int w = s.empty() ? n : n - s.top() - 1;
maxArea = max(maxArea, h * w);
}
return maxArea;
}
算法思路
-
使用栈来追踪柱子的索引:
- 栈用于追踪当前直方图中柱子的索引,保证栈中的柱子高度是递增的。
- 对于每个柱子(
array[i]),我们不断弹出栈中的柱子,直到栈顶柱子的高度小于当前柱子的高度。每次弹出一个柱子时,我们可以计算以该柱子为高的矩形面积。
-
计算最大矩形面积:
- 每次弹出栈顶元素时,假设该元素为矩形的高度,矩形的宽度为从该柱子到当前柱子之前的柱子之间的距离。
- 通过不断更新面积,最终找到最大的矩形。
-
处理栈中剩余的柱子:
- 在遍历所有柱子后,栈中仍可能有柱子,这些柱子表示高度还可以延续到数组的末尾,因此需要继续计算它们的最大面积。
时间和空间复杂度
- 时间复杂度:
O(n)。每个柱子至多入栈和出栈一次,因此时间复杂度是线性的。 - 空间复杂度:
O(n)。栈最多存储n个元素(即柱子的索引)。 - 以上就是我的该题解决策略。