84. 柱状图中最大的矩形 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。

本文介绍了一种使用单调栈解决最大矩形面积问题的方法。通过两次遍历数组,找到每个高度的左右边界,进而计算出最大面积。这种方法的时间复杂度为O(N),空间复杂度为O(N)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


2022兴业银行笔试题

暴力法(超时)

核心思想就是左右两开花,向左和向右分别找到大于等于自己的数字,然后记录下位置,在比较自己面积和左右面积之和。

public class Solution {

    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        
        if (len == 0) {
            return 0;
        }

        int res = 0;
        for (int i = 0; i < len; i++) {

            // 找左边最后 1 个大于等于 heights[i] 的下标
            int left = i;
            int curHeight = heights[i];
            while (left > 0 && heights[left - 1] >= curHeight) {
                left--;
            }

            // 找右边最后 1 个大于等于 heights[i] 的索引
            int right = i;
            while (right < len - 1 && heights[right + 1] >= curHeight) {
                right++;
            }

            int width = right - left + 1;
            res = Math.max(res, width * curHeight);
        }
        return res;
    }
}

复杂度分析:

时间复杂度:O(N^2)O(N )2
),这里 NN 是输入数组的长度。
空间复杂度:O(1)O(1)

单调栈

单调栈
单调栈分为单调递增栈和单调递减栈
11. 单调递增栈即栈内元素保持单调递增的栈
12. 同理单调递减栈即栈内元素保持单调递减的栈

操作规则(下面都以单调递增栈为例)
21. 如果新的元素比栈顶元素大,就入栈
22. 如果新的元素较小,那就一直把栈内元素弹出来,直到栈顶比新元素小

加入这样一个规则之后,会有什么效果
31. 栈内的元素是递增的
32. 当元素出栈时,说明这个新元素是出栈元素向后找第一个比其小的元素

举个例子,配合下图,现在索引在 6 ,栈里是 1 5 6
接下来新元素是 2 ,那么 6 需要出栈。
当 6 出栈时,右边 2 代表是 6 右边第一个比 6 小的元素。

当元素出栈后,说明新栈顶元素是出栈元素向前找第一个比其小的元素
当 6 出栈时,5 成为新的栈顶,那么 5 就是 6 左边第一个比 6 小的元素。
代码模板

C++

stack<int> st;
for(int i = 0; i < nums.size(); i++)
{
	while(!st.empty() && st.top() > nums[i])
	{
		st.pop();
	}
	st.push(nums[i]);
}

画图理解

在这里插入图片描述
思路
1 对于一个高度,如果能得到向左和向右的边界
2 那么就能对每个高度求一次面积
3 遍历所有高度,即可得出最大面积
4 使用单调栈,在出栈操作时得到前后边界并计算面积

class Solution {
    public int largestRectangleArea(int[] heights) {
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        int[] new_heights = new int[heights.length + 2];
        for (int i = 1; i < heights.length + 1; i++) {
            new_heights[i] = heights[i - 1];
        }
        for (int i = 0; i < new_heights.length; i++) {
            while (!stack.isEmpty() && new_heights[stack.peek()] > new_heights[i]) {
                int cur = stack.pop();
                int l = stack.peek();
                int r = i;
                res = Math.max(res, (r - l - 1) * new_heights[cur]);
            }
            stack.push(i);
        }
        return res;
    }
}

复杂度分析:

时间复杂度:O(N),输入数组里的每一个元素入栈一次,出栈一次。
空间复杂度:O(N),栈的空间最多为 N。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值