leetcode.85. 最大矩形(单调栈-java)

265 篇文章 2 订阅
235 篇文章 0 订阅

leetcode.85. 最大矩形

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximal-rectangle

题目描述

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

示例1:
在这里插入图片描述
输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:6
解释:最大矩形如上图所示。

示例 2:
输入:matrix = []
输出:0

示例 3:
输入:matrix = [[“0”]]
输出:0

示例 4:
输入:matrix = [[“1”]]
输出:1

示例 5:
输入:matrix = [[“0”,“0”]]
输出:0

提示:
rows == matrix.length
cols == matrix[0].length
1 <= row, cols <= 200
matrix[i][j] 为 ‘0’ 或 ‘1’

单调栈加数组优化栈

解题思路:
我们以以第一行为基座,生成每一列的矩形大小,从上往下加,遇到1,就相加,遇到0 ,就说明矩形中断了,我们就让他变成0,
如图所示:
在这里插入图片描述
如图所示:以第一行为基座,最后生成类似下面这个图形,是不是就类似:leetcode84. 柱状图中最大的矩形
,遍历每一列的位置,以当前位置为最小值,查到能覆盖的最大范围,求出矩形的数据量.循环遍历后,就能求出最大值了.
这题也是单调栈的应用,

单调栈的流程:
以一个例子来说明:
单调栈分为单调递增栈和单调递减栈
11. 单调递增栈即栈内元素保持单调递增的栈
12. 同理单调递减栈即栈内元素保持单调递减的栈
操作规则(下面都以单调递增栈为例)
21. 如果新的元素比栈顶元素大,就入栈
22. 如果新的元素较小,那就一直把栈内元素弹出来,直到栈顶比新元素小
加入这样一个规则之后,会有什么效果
31. 栈内的元素是递增的
32. 当元素出栈时,说明这个新元素是出栈元素向后找第一个比其小的元素
举个例子,配合下图,现在索引在 6 ,栈里是 1 5 6 。
接下来新元素是 2 ,那么 6 需要出栈。
当 6 出栈时,右边 2 代表是 6 右边第一个比 6 小的元素。
当元素出栈后,说明新栈顶元素是出栈元素向前找第一个比其小的元素
当 6 出栈时,5 成为新的栈顶,那么 5 就是 6 左边第一个比 6 小的元素。
在这里插入图片描述

代码演示

 /**
   * 最大矩形面积
   * @param matrix
   * @return
   */
  public int maximalRectangle(char[][] matrix) {
      if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
          return 0;
      }
      int cL = matrix[0].length;
      int maxArea = 0;
      int[] height = new int[cL];
      //以第一行为基座,求出每一列的矩形大小
      for (int i  = 0 ; i < matrix.length;i++){
          for (int j  = 0;j < cL;j++){
              height[j] = matrix[i][j] == '0' ? 0 : height[j] + 1;
          }
          maxArea = Math.max(maxArea,maxRecFromBottom(height));
      }
      return maxArea;
  }

  /**
   * 计算当前行时,最大的矩形面积,单调栈的方式求
   * @param height
   * @return
   */
  public int maxRecFromBottom(int[]height){
      int N = height.length;
      //用数组来优化栈结构,常数时间会更好
      int[]stack = new int[N];
      //维护栈的实际长度
      int stackSize = 0;
      int maxArea = 0;
      for (int i = 0; i < N;i++){
          while(stackSize != 0 && height[stack[stackSize - 1]] >= height[i]){
              int J = stack[--stackSize];
              //左边界
              int left = stackSize == 0 ? -1 : stack[stackSize - 1];
              int area = (i - left - 1) * height[J];
              maxArea = Math.max(maxArea,area);
          }
          stack[stackSize++] = i;
      }
      while (stackSize != 0 ){
          int J = stack[--stackSize];
          int left = stackSize == 0 ? -1 : stack[stackSize - 1];
          int area = (N - left - 1) * height[J];
          maxArea = Math.max(maxArea,area);
      }
      return maxArea;
  }

单调栈专题

单调栈的实现-单调递减栈和单调递增栈

leetcode1856. 子数组最小乘积的最大值

leetcode84. 柱状图中最大的矩形

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值