leetcode面试准备: Maximal Rectangle

1 题目

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

接口: int maximalRectangle(char[][] matrix)

2 思路

这是一道非常综合的题目,要求在0-1矩阵中找出面积最大的全1矩阵。刚看到这道题会比较无从下手,brute force就是对于每个矩阵都看一下,总共有m(m+1)/2*n(n+1)/2个子矩阵(原理跟字符串子串类似,字符串的子串数有n(n+1)/2,只是这里是二维情形,所以是两个相乘),复杂度相当高,肯定不是面试官想要的答案,就不继续想下去了。

这道题的解法灵感来自于Largest Rectangle in Histogram这道题,假设我们把矩阵沿着某一行切下来,然后把切的行作为底面,将自底面往上的矩阵看成一个直方图(histogram)。直方图的中每个项的高度就是从底面行开始往上1的数量。根据Largest Rectangle in Histogram我们就可以求出当前行作为矩阵下边缘的一个最大矩阵。接下来如果对每一行都做一次Largest Rectangle in Histogram,从其中选出最大的矩阵,那么它就是整个矩阵中面积最大的子矩阵。

算法的基本思路已经出来了,剩下的就是一些节省时间空间的问题了。

我们如何计算某一行为底面时直方图的高度呢? 如果重新计算,那么每次需要的计算数量就是当前行数乘以列数。然而在这里我们会发现一些动态规划的踪迹,如果我们知道上一行直方图的高度,我们只需要看新加进来的行(底面)上对应的列元素是不是0,如果是,则高度是0,否则则是上一行直方图的高度加1。利用历史信息,我们就可以在线行时间内完成对高度的更新。我们知道,Largest Rectangle in Histogram的算法复杂度是O(n)。所以完成对一行为底边的矩阵求解复杂度是O(n+n)=O(n)。接下来对每一行都做一次,那么算法总时间复杂度是O(m*n)。

空间上,我们只需要保存上一行直方图的高度O(n),加上Largest Rectangle in Histogram中所使用的空间O(n),所以总空间复杂度还是O(n)

复杂度: Time: O(m*n); Space: O(n)

3 代码

	public int maximalRectangle(char[][] matrix) {
int result = 0;
int row = matrix.length;
if (matrix == null || row == 0) {
return result;
}
int col = matrix[0].length; // O(n)空间
int[] height = new int[col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (matrix[i][j] == '0') {
height[j] = 0;
} else {
height[j] += 1;
}
}
result = Math.max(result, largestRectangleArea(height));
}
return result;
} private int largestRectangleArea(int[] height) {
int result = 0;
int len = height.length;
Deque<Integer> stack = new LinkedList<Integer>();
for (int i = 0; i < len;) {
if (stack.isEmpty() || height[stack.peek()] < height[i]) {
stack.push(i);
i++;
} else {
int tmp = stack.pop();
int count = stack.isEmpty() ? i : i - stack.peek() - 1;
result = Math.max(result, count * height[tmp]);
}
} while (!stack.isEmpty()) {
int tmp = stack.pop();
int count = stack.isEmpty() ? len : len - stack.peek() - 1;
result = Math.max(result, count * height[tmp]);
}
return result;
}

4 总结

O(m*n)时间内就可以完成对最大矩阵的搜索。动态规划、栈的思想。

5 参考

leetcode面试准备: Maximal Rectangle的更多相关文章

  1. 【LeetCode】85. Maximal Rectangle

    Maximal Rectangle Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle conta ...

  2. 【leetcode】85. Maximal Rectangle(单调栈)

    Given a rows x cols binary matrix filled with 0's and 1's, find the largest rectangle containing onl ...

  3. 【LeetCode】85. Maximal Rectangle 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/maximal- ...

  4. 【一天一道LeetCode】#85. Maximal Rectangle

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  5. LeetCode OJ 85. Maximal Rectangle

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and ...

  6. LeetCode OJ:Maximal Rectangle(最大矩形)

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and ...

  7. LeetCode解题报告—— Maximal Rectangle

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and ...

  8. 【LeetCode】085. Maximal Rectangle

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's ...

  9. LeetCode OJ 之 Maximal Square (最大的正方形)

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ...

随机推荐

  1. centos 6.4 Apache 配置 flv mp4.h264 流媒体拖动

    http://blog.csdn.net/xst686/article/details/9763995 加入流媒体扩展后要重启 httpd flv 流媒体 <textarea style=&qu ...

  2. iOS 各种控件默认高度

    1.状态栏 状态栏一般高度为20像素,在打手机或者显示消息时会放大到40像素高,注意,两倍高度的状态栏在好像只能在纵向的模式下使用.如下图   用户可以隐藏状态栏,也可以将状态栏设置为灰色,黑色或者半 ...

  3. java中的异常处理机制_finally的使用

    finally总结: finally代码块:定义一定执行的代码 通常用于关闭资源或者某些一定执行的代码 实例1:finally功能演示 class FuShuException extends Exc ...

  4. tomcat错误信息解决方案【严重:StandardServer.await: create[8005]

    1.独立运行的tomcat.exe没有关闭,关闭tomcat图标并结束掉tomcat进程.(我是这个原因,在开始菜单里找到tomcat,然后stop它) 2.安装了其他的软件占用了8080端口,tom ...

  5. C语言 goto, return等跳转

    C语言 goto, return等跳转 Please don't fall into the trap of believing that I am terribly dogmatical about ...

  6. hdu 1063 Exponentiation (高精度小数乘法)

    //大数继续,额,要吐了. Problem Description Problems involving the computation of exact values of very large m ...

  7. Javascript中的迭代、归并方法

    迭代方法 在Javascript中迭代方法个人觉得尤为重要,在很多时候都会有实际上的需求,javascript提供了5个迭代方法来供我们操作,它们分别为: every() 对数组中的每一个项运用给定的 ...

  8. Qt-获取网络接口信息的综合示例

    在前面的文章中介绍了与 获 取 本 机 网 络 信 息 相 关 的 类 常 用 的 有 4 个 , 分 别 是 : QHostAddress, QHostInfo, QNetworkInterface ...

  9. 掌握 ActionResult

    我在上一篇博客不要停留在表面,MVC 3 我们要深入一些 说明了我们的掌握程度还是不够,还需要我们继续努力.但是有园友质疑说他们认为我说的只是书院派,并不实用,这令作为程序员的我很是生气.好吧,那咱们 ...

  10. 懒加载 lazy load

    懒加载(Load On Demand)是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据, 而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用. 比 ...