力扣85-最大矩形(巧妙利用上一题解答 Java版题解)

力扣85-最大矩形

一、原题题目

1.1 题目

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

1.2 示例

  • 示例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

提示:

  • row == matrix.length
  • cols == matrix[0].length
  • 0 <= row, cols <= 200
  • matrix[i][j]01

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

二、解题思路

  • 解题思路

  这个题基于力扣第84题-柱状图中最大的矩形可以比较容易的想到思路,我们可以一行一行的考虑最大的矩形,如图所示。利用上一题的思路还是很容易想到解题思路的。

递归执行结果
  • 详细代码(Java)
public int maximalRectangle(char[][] matrix) {
    if(matrix.length == 0|| matrix == null) return 0;   // 当字符二维数组不存在输出0
    int[] a = new int[matrix[0].length];        // 记录每一行中每一个位置向上连续1的个数
    int max = 0;        // 记录最大的矩形面积,初始化为0
    for (int i = 0;i<matrix.length;i++){        // 遍历每一行
      for (int j = 0;j<matrix[0].length;j++){ // 统计每一个位置向上连续1的个数
        int count = 0;      // 每一个位置初始化向上连续1的个数为0
        for (int k = i;k>=0;k--){   // 向上遍历
          if (matrix[k][j]=='1')count++;
          else break;
        }
        a[j] = count;
      }
      max = Math.max(max,largestRectangleArea(a));
    }
    return max;
}
// 第84题-柱状图中最大的矩形
public int largestRectangleArea(int[] heights) {
    if (heights == null || heights.length==0)   return 0;   // 数组为空返回0
    int len = heights.length;       // 记录长度
    int Smax = 0;                   // 记录最大面积
    Deque<Integer> stack = new ArrayDeque<>(len);
    for (int i =0;i<len;i++){       // 遍历每一个元素
      // 栈不为空,且当前元素小于栈顶元素,则计算栈顶元素能勾勒矩形的面积
      while (!stack.isEmpty()&&heights[i]<heights[stack.peekLast()]){
        int right = i;          // 右边界为当前下标
        int height = heights[stack.pollLast()]; // 栈顶出栈记录高度
        int left = stack.isEmpty()?-1:stack.peekLast();  // 左边界:栈不空则为栈顶元素,否则为-1
        Smax = Math.max(Smax,height*(right-left-1));    // 计算面积比较
      }
      stack.addLast(i);   // 栈顶元素不大于当前值,入栈
    }
    while (!stack.isEmpty()){   // 遍历完了数组
      int right = len;        // 右边界为数组长度
      int height = heights[stack.pollLast()]; // 栈顶出栈记录高度
      int left = stack.isEmpty()?-1:stack.peekLast(); // 左边界:栈不空则为栈顶元素,否则为-1
      Smax = Math.max(Smax,height*(right-left-1));    // 计算面积比较
    }
    return Smax;
}
  • 代码执行结果
递归执行结果

三、总结

  这两天的题目都是困难,做的很吃力,这个题就先这样做着吧,后面有精力在分析多方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ItDaChuang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值