[leetcode 85. 最大矩形] 单调栈--84题的简单扩展

题目描述

给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例:

输入:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
输出: 6

解题思路

假设矩阵中存在一个最大矩形,我们不妨将它底边一下的矩阵挡住,把“1”看作实心柱体,把“0”看作空心,跟84题就非常相似了。唯一不同的就是,我们这里还有一些悬空的柱子。不过没有关系,我们把它的高度记为0之后,并不会影响计算最大的面积。那么接下来就很思路清晰了:

  • 将矩阵的每一层单独拿出来,看作是一个84题的重复
  • 计算之前,我们先更新每一层的高度数组
  • 重复84题的计算

代码

/**
 * @param {character[][]} matrix
 * @return {number}
 */
var maximalRectangle = function(matrix) {
    let heights = [], max = 0;
    for (let i=0;i<matrix.length;i++) {
        if (heights.length == 0) {
            // init
            // 前后补0,使代码更简洁
            for (let k=0;k<matrix[i].length+2;k++) {
                heights[k] = 0;
            }
        }
        let stack = [];
        for (let j=0;j<heights.length;j++) {
            // 同步更新每一个柱子的高度
            heights[j] = j>0&&j<=matrix[i].length&&‘1‘==matrix[i][j-1] ? heights[j]+1 : 0;
            // 计算每一个单调递增栈
            while (stack.length>0 && heights[j] < heights[stack[stack.length-1]]) {
                max = Math.max(max, heights[stack.pop()]*(j-stack[stack.length-1]-1));
            }
            stack.push(j);
        }
    }
    return max;
};

原文地址:https://www.cnblogs.com/dapianzi/p/12704556.html

时间: 2024-10-06 13:59:31

[leetcode 85. 最大矩形] 单调栈--84题的简单扩展的相关文章

[51nod1102]面积最大的矩形(单调栈||预处理)

题意:求序列上某区间最小值乘区间长度的最大值. 解题关键:很早就在<挑战程序设计竞赛>中见过了,单调栈模板题,注意弹栈时如何处理后面的元素. 法一:单调栈 #include<bits/stdc++.h> using namespace std; typedef long long ll; stack<int>s; ll a[50002]; int main(){ int n; cin>>n; for(int i=0;i<n;i++) cin>&g

Leetcode84. 柱状图中最大的矩形(单调栈)

84. 柱状图中最大的矩形 前置 单调栈 做法 连续区间组成的矩形,是看最短的那一块,求出每一块左边第一个小于其高度的位置,右边也同理,此块作为最短限制.需要两次单调栈 单调栈维护递增区间,每次不满足弹出栈顶,顺便利用此栈顶和当前位置计算栈顶能覆盖的长度 用来计算.仅需一次单调栈 原文地址:https://www.cnblogs.com/y2823774827y/p/11261446.html

[leetcode] 85. 最大矩形

85. 最大矩形 解法1: 一个思路就是这个可以看作84. 柱状图中最大的矩形的扩展,这道题的二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图,对每个直方图都调用 84. 柱状图中最大的矩形 中的方法,就可以得到最大的矩形面积. class Solution { public int maximalRectangle(char[][] matrix) { int m = matrix.length; if (m == 0) return 0; int n = ma

AcWing - 131 - 直方图中最大的矩形 = 单调栈

https://www.acwing.com/problem/content/133/ 单调栈的模板题,按道理悬线dp不用的话也可以这样做. 需要注意这道题不能直接dp,比如[3,5,4],这组数据,3可以拓展5,但5不能拓展4,不过3可以拓展4. #include<bits/stdc++.h> using namespace std; typedef long long ll; int n; ll a[100005]; int l[100005]; int r[100005]; stack&

Maximum Xor Secondary(单调栈好题)

Maximum Xor Secondary CodeForces - 280B Bike loves looking for the second maximum element in the sequence. The second maximum element in the sequence of distinct numbers x1,?x2,?...,?xk (k?>?1) is such maximum element xj, that the following inequalit

单调栈模板题 luogu P2659

题目链接:https://www.luogu.org/problem/P2659 实际上就是要我们求出每个数字左右两边第一个小于它的数字位置,然后两个位置所在的开区间长度乘以这个数字,取最大值输出. 因为是求两边第一个小于a[i]的数字,所以我们弄一个递增(其实是不减小就可以了,可以有相同大小的元素)的单调栈,从栈底到栈顶的数字是依次增大的,在求的过程中要始终保持递增的性质.我们每次在数字入栈时求出数字左边第一个小于它的数字位置,在出栈的时候求出右边第一个小于它的数字位置,为什么是这样,看下面,

51nod1158 最大子矩形 单调栈应用

#include<iostream> #include<cstring> #include<cstdio> using namespace std; int mp[600][600],m,n,ans; void work(int i){//以第i行为底的矩阵 int stk[600],w[600]={},h[600]={},top=0;//高度栈,左宽栈 memset(stk,-1,sizeof stk); for(int j=1;j<=m;j++)h[j]=mp

poj2796 Feel Good 单调栈

题意:给定一个序列,需要找出某个子序列S使得Min(a[i])*Σa[i] (i属于S序列)最大 正解:单调栈 这题的暴力还是很好想的,只需3分钟的事就可以码完,以每个点拓展即可,但这样的复杂度是O(n^2)的,肯定会TLE 以暴力的思想作为基础,再进行深层次思考,考虑每个点往周围拓展的时候,都要走到最远的地方停下来,也就是说会有一个左上限,一个右上限(命名为:pre.next),不难发现再枚举5.4.3.2.1这个序列的时候,每次都要往左扫描到最左边,显然这是做了重复的事情,于是机智的我马上想

解题报告 『HISTOGRA - Largest Rectangle in a Histogram(单调栈)』

原题地址 单调栈板子题,代码很简单. 注意将a[n + 1]赋值为0,防止栈中矩形未弹完. 代码实现如下: #include <bits/stdc++.h> using namespace std; #define LL long long #define rep(i, a, b) for (register int i = a; i <= b; i++) const int maxn = 1e5 + 5; int n; int a[maxn], sta[maxn], wid[maxn]