问题描述
小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) 的最大值。
算法选择
贪心
算法思路
-
初始化:创建一个空的单调栈,用于存储数组元素的索引。同时,创建一个变量
maxArea来存储最大矩形面积。 -
遍历数组:从左到右遍历数组
array。 -
维护单调栈:
- 如果当前元素
array[i]大于或等于栈顶元素对应的数组值,将当前索引i推入栈中。 - 如果当前元素
array[i]小于栈顶元素对应的数组值,说明栈顶元素对应的数组值是它能作为最小值的矩形的右边界。此时,我们从栈中弹出栈顶元素,计算以这个元素为最小值的矩形面积,并更新maxArea。
- 如果当前元素
-
计算矩形面积:当从栈中弹出一个元素时,我们知道了这个元素作为最小值的矩形的左右边界。左边界是当前栈顶元素的下一个元素(如果栈不为空),右边界是当前遍历到的元素
i。因此,矩形的宽度是i - stack.peek() - 1(如果栈为空,则宽度是i)。矩形的高度是弹出元素对应的数组值。所以,矩形的面积是height * width。 -
处理剩余元素:遍历结束后,栈中可能还有剩余的元素。这些元素对应的矩形的右边界是数组的末尾。我们继续从栈中弹出元素,计算矩形面积,并更新
maxArea。 -
返回结果:最后,
maxArea存储的就是最大矩形面积。
代码展示
public class Main {
public static int solution(int n, int[] array) {
// Edit your code here
int ans = 0;
for (int i = 0; i < n - 1; i++) {
int min = array[i];
for (int j = i; j < n; j++) {
min = Math.min(min, array[j]);
ans = Math.max(ans, (j - i + 1) * min);
}
}
return ans;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(5, new int[] { 1, 2, 3, 4, 5 }) == 9);
}
}