题目:
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
For example, given the following matrix:
1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0Return 6
题解:
这个题是在 Largest Rectangle in Histogram上的延伸,二维矩阵每一行为底,都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图,循环调用直方图最大面积函数即可。
Solution
class Solution { public: int maximalRectangle(vector<vector<char>>& matrix) { int res = 0; if(matrix.empty()) return res; int n = matrix[0].size(); vector<int> cals(n, 0); for(int i = 0; i < matrix.size(); ++i){ for(int j = 0; j < n; ++j){ cals[j] = matrix[i][j] == '0' ? 0 : cals[j] + 1; } res = max(res, maxRectangleArea(cals)); } return res; } private: int maxRectangleArea(vector<int> &nums){ int n = nums.size(); int res = 0, area = 0; nums.push_back(0); stack<int> s; for(int i = 0; i <= n;){ if(s.empty() || nums[s.top()] <= nums[i]) s.push(i++); else { int cur = s.top(); s.pop(); area = nums[cur] * (s.empty() ? i : (i - s.top() - 1)); res = max(res, area); } } return res; } };
left数组表示左边界是1的位置,right数组表示右边界是1的位置,那么对于任意一行的第j个位置,矩形为(right[j] - left[j]) * height[j]
Solution 2 动态规划
class Solution { public: int maximalRectangle(vector<vector<char>>& matrix) { int res = 0; if(matrix.empty()) return res; int n = matrix[0].size(); vector<int> height(n, 0), left(n, 0), right(n, n); for(int i = 0; i < matrix.size(); ++i){ int l = 0, r = n; for(int j = 0; j < n; ++j){ if(matrix[i][j] == '1'){ ++height[j]; left[j] = max(left[j], l); } else { l = j + 1; height[j] = 0; left[j] = 0; right[j] = n; } } for(int j = n - 1; j >= 0; --j){ if(matrix[i][j] == '1'){ right[j] = min(right[j], r); res = max(res, height[j] * (right[j] - left[j])); } else { r = j; } } } return res; } };