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的矩阵,要求出范围全为1的矩阵的面积。
算法一,动态规划
此题,以每行为底,都可以转换成是一个Largest
Rectangle in Histogram问题。
每个点,先算出所在矩形的高度,左边界,右边界。然后就能求出这个点所在矩形的面积了。
而高度,左边界,右边界,都可以按照DP思路算出。
已知上一行的高度,如果当前元素为1,则高度+1,否则清0.
left(i,j) = max(left(i-1,j), curleft) 逐步向右收缩其左边矩
right(i,j) = min(right(i-1,j), curright) 逐步向左收缩其右边矩
对curleft设置,如果当前元素为1,则不修改curleft。否则将其置0。置0,意味着下一行,该列时,其左边界,可能延伸至最起始处。即它之前,全为1.
同理,对curright,当前元素为0时,将其置为一个大值。本行度高度为0了。但下一行的,该列时,其右边界,可能延伸到最远处。即在他之后,全为1.
此代码在leetcode上实际执行时间为18ms。
class Solution { public: int maximalRectangle(vector<vector<char> > &matrix) { if (matrix.empty() || matrix[0].empty()) return 0; int area = 0; const int m = matrix.size(); const int n = matrix[0].size(); vector<int> height(n); vector<int> left(n); vector<int> right(n, n); for (int i=0; i<m; i++) { int curLeft = 0; for (int j=0; j<n; j++) { height[j] = matrix[i][j] == '1' ? height[j]+1 : 0; left[j] = matrix[i][j] == '1' ? max(left[j], curLeft) : 0; curLeft = matrix[i][j] == '1' ? curLeft : j+1; } int curRight = n-1; for (int j=n-1; j>=0; j--) { right[j] = matrix[i][j] == '1' ? min(right[j], curRight) : n; curRight = matrix[i][j] == '1' ? curRight : j-1; } for (int j=0; j<n; j++) area = max(area, (right[j]-left[j]+1)*height[j]); } return area; } };
https://leetcode.com/discuss/20240/share-my-dp-solution
算法二。借鉴题目Largest Rectangle in Histogram的解法。
此题,以每行为底,都可以转换成是一个Largest Rectangle in Histogram问题。
不同的是,高度表height,需要自己算。
求出height后,其他同Largest Rectangle in Histogram思路一样。
class Solution { public: int maximalRectangle(vector<vector<char> > &matrix) { if (matrix.empty() || matrix[0].empty()) return 0; int area = 0; const int m = matrix.size(); const int n = matrix[0].size(); vector<int> height(n+1); for (int i=0; i<m; i++) { stack<int> s; bool flag = true; for (int j=0; j<=n;) { if (flag && j!=n) { height[j] = matrix[i][j]=='1' ? height[j]+1 : 0; flag = false; } if (s.empty() || height[j] >= height[s.top()]) { s.push(j++); flag = true; } else { const int altitude = height[s.top()]; s.pop(); const int left = s.empty() ? 0 : s.top()+1; area = max(area, (j-left) * altitude); } } } return area; } };
原文:http://blog.csdn.net/elton_xiao/article/details/45128267