Maximal Rectangle

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

这题是一道难度很大的题目,至少我刚开始的时候完全不知道怎么做,也是google了才知道的。

这题要求在一个矩阵里面求出全部包含1的最大矩形面积,譬如这个:

  1. 0 0 0 0
  2. 1 1 1 1
  3. 1 1 1 0
  4. 0 1 0 0

我们可以知道,最大的矩形面积为6。也就是下图中虚线包围的区域。那么我们如何得到这个区域呢?

  1. 0 0 0 0
  2. |--------|
  3. |1 1 1 |1
  4. |1 1 1 |0
  5. |--------|
  6. 0 1 0 0

对于上面哪一题,我们先去掉最下面的一行,然后就可以发现,它可以转化成一个直方图,数据为[2, 2, 2, 0],我们认为1就是高度,如果碰到0,譬如上面最右列,则高度为0,而计算这个直方图最大矩形面积就很容易了,我们已经在Largest Rectangle in Histogram处理了。

所以我们可以首先得到每一行的直方图,分别求出改直方图的最大区域,最后就能得到结果了。

代码如下:

  1. class Solution {
  2. public:
  3. int maximalRectangle(vector<vector<char> > &matrix) {
  4. if(matrix.empty() || matrix[0].empty()) {
  5. return 0;
  6. }
  7. int m = matrix.size();
  8. int n = matrix[0].size();
  9. vector<vector<int> > height(m, vector<int>(n, 0));
  10. for(int i = 0; i < m; i++) {
  11. for(int j = 0; j < n; j++) {
  12. if(matrix[i][j] == '0') {
  13. height[i][j] = 0;
  14. } else {
  15. height[i][j] = (i == 0) ? 1 : height[i - 1][j] + 1;
  16. }
  17. }
  18. }
  19. int maxArea = 0;
  20. for(int i = 0; i < m; i++) {
  21. maxArea = max(maxArea, largestRectangleArea(height[i]));
  22. }
  23. return maxArea;
  24. }
  25. int largestRectangleArea(vector<int> &height) {
  26. vector<int> s;
  27. height.push_back(0);
  28. int sum = 0;
  29. int i = 0;
  30. while(i < height.size()) {
  31. if(s.empty() || height[i] > height[s.back()]) {
  32. s.push_back(i);
  33. i++;
  34. } else {
  35. int t = s.back();
  36. s.pop_back();
  37. sum = max(sum, height[t] * (s.empty() ? i : i - s.back() - 1));
  38. }
  39. }
  40. return sum;
  41. }
  42. };