最大矩形面积问题
问题描述
小S最近在分析一个数组 ,数组的每个元素代表某种高度。小S对这些高度感兴趣的是,当我们选取任意 kk个相邻元素时,如何计算它们所能形成的最大矩形面积。
对于 k个相邻的元素,我们定义其矩形的最大面积为:
R(k)=k×min(h[i],h[i+1],...,h[i+k−1]) 即,R(k)的值为这 k个相邻元素中的最小值乘以 k。现在,小S希望你能帮他找出对于任意 k,R(k)的最大值。
思路
问题描述说的很清楚,就是求一段子数组,长度为k, 这段子数组的最小值乘以长度的最大值。拿到这题没有头绪,开始思考暴力解:可以遍历数组,视每个遍历到的元素为最小值,然后开始向左向右开始寻找边界,即第一个比当前值小的值,得到以当前值为最小值且符合要求的最大值,和原先得到最大值比较,从而确定最大矩形面积,这样的时间复杂的为, 空间复杂度为, 这样解大概率会被卡时间复杂度,遂而想其它思路优化,想了大概一两分钟,没有头绪,问豆包,然后它给出以下代码,然后试了下,发现过了。
import java.util.Stack;
public class Main {
public static int solution(int n, int[] array) {
// Edit your code here
int maxArea = 0;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i <= n; i ++) {
// 当前高度
int currentHeight = i == n ? 0 : array[i];
while (!stack.isEmpty() && currentHeight < array[stack.peek()]) {
int height = array[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, width * height);
}
stack.push(i);
}
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);
}
}
看了下代码,发现它用的是单调栈。它是维护一个单调递增栈,每次当遍历到一个元素时,那它去和栈顶元素相比较,如果小于栈顶元素,则弹出栈顶元素,直到栈为空或者栈顶元素对应的数组值小于当前元素。每次弹出去的元素然后就被视为以该元素为最小值,i和栈顶元素的下标为左右边界,这样就能以时间复杂度为,空间复杂度为过掉该题。
为什么每次出栈的元素都是在某一区间的最小元素:左边比它大的元素早在它刚开始入栈的时候就已经出栈,右边是第一个值小于它的,所以左右边界就可以确定且在该区间内的最小元素。
彩蛋
本来栈可能遍历所有元素之后栈还不为空,需要在循环外再写一套相同的处理逻辑,代码写起来有点臃肿,但是这个这里直接到了, 然后设置当前值为0,小于所有的值,这些全部出栈,不需要写额外的处理逻辑
总结
AI真好用