- 转载请注明作者和出处:http://blog.csdn.net/u011475210
- 代码地址:https://github.com/WordZzzz/Note/tree/master/LeetCode
- 刷题平台:https://www.nowcoder.com/ta/leetcode
- 题 库:Leetcode经典编程题
- 编 者:WordZzzz
[toc]
题目描述
Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing all ones and return its area.
给定一个用0和1填充的2D二进制矩阵,找到包含所有1的最大矩形并返回其面积。
解题思路
刚看到这道题的时候,一脸无奈。我们还是先来看一下Largest Rectangle in Histogram这道题目吧。
Largest Rectangle in Histogram
Given n non-negative integers representing the histogram’s bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
The largest rectangle is shown in the shaded area, which has area = 10 unit.
For example,
Given heights = [2,1,5,6,2,3],
return 10.
我们先把代码贴出来,然后边看代码边捋清思路。
1 | class Solution { |
- 首先,我们需要新建stack来保存遍历过程中的递增序列。如果栈是空的,那么索引i入栈。所以当i=0时,将0入栈。注意栈内保存的是索引,不是高度。然后i++。
- 当i=1的时候,发现height[i]小于了栈内的元素,于是出栈。这时候stack为空,所以面积的计算是height[t] * i。t是刚刚弹出的stack顶元素。也就是蓝色部分的面积。
- 这时候stack为空了,那就继续入栈。注意到只要是连续递增的序列,我们都要keep pushing,直到我们遇到了i=4,height[i]=2小于了栈顶的元素。
- 这时候开始计算矩形面积。首先弹出栈顶元素,t=3。即下图绿色部分。
- 接下来注意到栈顶的(索引指向的)元素还是大于当前i指向的元素,于是出栈,并继续计算面积,桃红色部分。
- 最后,栈顶的(索引指向的)元素大于了当前i指向的元素,循环继续,入栈并推动i前进。直到我们再次遇到下降的元素,也就是我们最后人为添加的dummy元素0.
- 同理,我们计算栈内的面积。由于当前i是最小元素,所以所有的栈内元素都要被弹出并参与面积计算。
注意我们在计算面积的时候已经更新过了maxSize 。
我们可以看到,stack中总是保持递增的元素的索引,然后当遇到较小的元素后,依次出栈并计算栈中bar能围成的面积,直到栈中元素小于当前元素。
maximal-rectangle
这道题的解法灵感来自于Largest Rectangle in Histogram这道题,假设我们把矩阵沿着某一行切下来,然后把切的行作为底面,将自底面往上的矩阵看成一个直方图(histogram)。直方图的中每个项的高度就是从底面行开始往上1的数量。根据Largest Rectangle in Histogram中的largestRectangleArea函数我们就可以求出当前行作为矩阵下边缘的一个最大矩阵。接下来如果对每一行都做一次Largest Rectangle in Histogram,从其中选出最大的矩阵,那么它就是整个矩阵中面积最大的子矩阵。算法时间复杂度为O(m*n),这解法真是太棒了,其实应该算是动态规划的题目了。
C++版代码实现
1 | class Solution { |
系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz