问题描述
小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) 的最大值。
问题理解
我们需要在一个数组中找到任意 k 个相邻元素所能形成的最大矩形面积。矩形的面积定义为这 k 个元素中的最小值乘以 k。
数据结构选择
为了高效地解决这个问题,我们可以考虑使用栈来辅助计算。当我们遍历数组时,栈中的元素总是保持递增的顺序。这样,当我们遇到一个比栈顶元素小的高度时,我们可以确定栈顶元素对应的高度不能再向右扩展,因此可以计算以该高度为最小高度的矩形面积。
算法步骤
-
初始化:创建一个栈来存储数组的索引,初始化
maxArea为 0。 -
遍历数组:
- 如果当前高度小于栈顶元素对应的高度,则弹出栈顶元素,并计算以该高度为最小高度的矩形面积。
- 计算面积时,宽度为当前索引与新栈顶元素索引的差值。
- 更新
maxArea。
-
处理栈中剩余元素:遍历结束后,栈中可能还剩下一些元素,这些元素对应的高度可以延伸到数组的末尾,计算这些矩形的面积并更新
maxArea。
关键点
- 栈的使用:栈中存储的是数组的索引,而不是高度本身。
- 面积计算:每次弹出栈顶元素时,计算以该高度为最小高度的矩形面积。
具体代码
import java.util.Stack;
public class Main {
public static int solution(int n, int[] array) {
// 使用栈来辅助计算
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
// 遍历数组
for (int i = 0; i < n; i++) {
// 当栈不为空且当前高度小于栈顶高度时
while (!stack.isEmpty() && array[i] < array[stack.peek()]) {
// 弹出栈顶元素并计算面积
int height = array[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
// 将当前索引入栈
stack.push(i);
}
// 处理栈中剩余的元素
while (!stack.isEmpty()) {
int height = array[stack.pop()];
int width = stack.isEmpty() ? n : n - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
return maxArea;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(5, new int[]{1, 2, 3, 4, 5}) == 9);
System.out.println(solution(6, new int[]{5, 4, 3, 2, 1, 6}) == 9);
System.out.println(solution(4, new int[]{4, 4, 4, 4}) == 16);
}
}