leetcode刷题 | 直方图最大矩形面积和矩阵中最大的矩形

33 篇文章 1 订阅
29 篇文章 3 订阅

leetcode刷题 | 直方图最大矩形面积和矩阵中最大的矩形


两道题的解法比较类似,都是使用栈作为数据结构

直方图最大矩形面积

  • 对于任意的位置,想要找到以该位置为高h的矩形,可以以该位置为中心,分别向左右扩张找到以该位置为h的最大宽度。

  • 如何找到最大宽度?我们只需要找到距离该位置最近的左右两侧高度小于h的柱子,这样这两根柱子之间的高度均高于h,那么这就是我们要找到的最大宽度

  • 使用栈来保存数组的下标,栈中的值所对应到数组中的值,都是单调递递增的。

  • 当将index放入到栈中,首先需要判断该heights[index] 是否大于heights[stack.peek()],如果大于那么可以直接入栈,如果小于那么该位置index就是heights[stack.peek()]的右边界,也就是右边第一个小于高度为h的柱子

  • 然后移除栈顶,stack.pop(),这样stack.peek()就是左边第一个小于高度h的柱子,这样就找到以stack.pop()为高,index-stack.peek()-1为宽的矩形

  • 然后继续比较,直到全部比较完毕

  • 此时如果stack不为空的话,那么剩下的元素都是单调递增的,可以直接以stack.pop()为高,stack.size()-stack.peek()-1为宽度进行计算面积

  • 最后返会res;

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

矩阵中最大的矩形

和上一道题类似

  • 定义一个表示高度的数组heigths,表示从当前层到最底层连续都是1的最大高度
  • 通过上一道题的计算方式进行叠加
class Solution {
    public int maximalRectangle(String[] matrix) {
        if (matrix.length == 0) return  0;
        int res = 0;
        int[] heigths = new int[matrix[0].length()];
        for (String s : matrix) {
            for (int i = 0;i<heigths.length;i++){
                heigths[i] = s.charAt(i) == '0' ? 0:heigths[i]+1;
            }
            res  = Math.max(res,maximalRange(heigths));
        }
        return res;
    }
    public int maximalRange(int[] heigths){
        int l = heigths.length;
        int[] stack = new int[l+1];
        stack[0] = -1;
        int index = 1;
        int res = 0;
        for (int i = 0;i<l;i++){
            while (index > 0 && heigths[stack[index]] >= heigths[i]){
                res = Math.max(res,heigths[stack[index--]]*(i-stack[index]-1));
            }
            stack[++index] = i;
        }
        while (index > 0){
            res = Math.max(res,heigths[stack[index--]]*(l-stack[index]-1));
        }
        return res;
    }
}

图片可以参考花落&月缺大佬:https://leetcode.cn/problems/0ynMMM/solution/hua-luo-yue-que-wo-zhen-de-zhen-de-nu-li-ohjt/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小七rrrrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值