leetcode面试准备: Maximal Rectangle
2015-10-15 17:29
465 查看
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 参考
leetcodeCode Ganker征服代码
Maximal Rectangle
相关文章推荐
- 当看到《疯狂Java程序员的修养》这段代码的时候,我是真的搞蒙了,不知道怎么一回事代码如下:
- 黑马程序员——高新技术--反射
- 关于链表的面试问题(判断一个单链表中是否有环)
- 黑马程序员——反射
- 成为高效程序员的搜索技巧
- 黑马程序员 ——ios基础 ——字符串
- 黑马程序员 ——ios基础 ——冒泡排序、二维数组
- 黑马程序员 ——ios基础 ——#include文件搜索顺序、数组
- 黑马程序员 ——ios基础 ——函数
- 黑马程序员 ——ios基础 ——程序的流程控制
- 黑马程序员 ——ios基础 ——关键字、标示符、运算符
- 黑马程序员 ——ios基础 ——程序和数据储存、数据类型、printf函数
- 黑马程序员 ——ios基础 ——第一个C程序、常量、变量
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 【July程序员编程艺术】之寻找和为定值的两个或者多个数
- 我是怎么招聘程序员的
- 转自“展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告”
- 程序员重装系统后,要安装的工具
- 野生程序员的故事
- 黑马程序员——Java基础语法---数组