【Leetcode】84. Largest Rectangle in Histogram 85. Maximal Rectangle
问题描述:
84:直方图最大面积。
85:0,1矩阵最大全1子矩阵面积。
问题分析:
对于84,如果高度递增的话,那么OK没有问题,不断添加到栈里,最后一起算面积(当然,面积等于高度h * disPos,这里的高度取决于两个h的较小者,那么如果有序的话,只需要计算每一个最小值h,在用到当前位置与最小值h所在位置的差值,也就是柱子数目,就OK了)。如果新h[i]的高度比之前的高度小的话,那么就可以认为之前所有比h[i]高的柱子都需要计算一下面积,然后对于破坏递增规则的h[i]会继续加入栈中。为甚会酱婶儿呢,因为你想哈,如果h[i]是最大矩形的右边界那么h[i + 1]是不一定有:h[i]>h[i+ 1]。哎呀,不用想了,肯定是对的 ,如果h[i]<h[i+ 1],那我直接用i+1的柱子当右边界的话,面积肯定会更大的嘛!没错,这就是我们为什么会用一个数据结构来说维护一个递增的序列来求解问题的原因。
对于85,我说可以把他转换成84的求解形式,你信不信啊?不信的话,请看:
对于下面这个矩阵:
1 0 1 1 1
1 1 1 1 1
1 0 1 1 0
1 1 1 1 1
我们用一个数组height[]来计算当前row下,每一column之前row(i -> 0)有多少个连续的1。
row 0: 1 0 1 1 1
row 1: 2 1 2 2 2
row 2: 3 0 3 3 0
row 3: 4 1 4 4 1
我们对于每一行 row 来说,这个数字不就是表示的是当横轴在row处,直方图的高度吗!神奇,这样我们对于每一行都执行84中的算法,是不是就可以得到全局面积最大值了。
问题解决:
实现上使用stack来维护递增height,没有问题的。这里提前将原来的数组height压入了0,使得最后一定会使stack中的数弹出来。如果不压入,那么最后记得check一下stack也是可以的。
代码如下:
class Solution { public: int maximalRectangle(vector<vector<char>>& matrix) { if(matrix.size() == 0) return 0; int n = matrix.size(), m = matrix[0].size(); stack<int>sta; int maxArea = 0; vector<int>height(m + 1, 0); for(int i = 0; i < n; i ++){ for(int j = 0; j < m; j ++){ if(matrix[i][j] == '1') height[j] ++; else height[j] = 0; } while(!sta.empty()) sta.pop(); for(int j = 0; j < height.size(); j ++){ while( !sta.empty() && height[j] < height[sta.top()]){ int h = height[sta.top()]; sta.pop(); int idLeft = sta.size() > 0? sta.top(): -1; maxArea = max(maxArea, h * (j - idLeft - 1)); } sta.push(j); } } return maxArea; } };
PS: celebration , leetcode今天做完这两道题,已经干掉整100题了。不信? 哈哈 :
继续加油,别装逼~。~