2014.2.26 20:27
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.
Solution:
The worst solution for this problem should be O(n^4), and you will use O(n^2) space to speed it up to O(n^3).
But we're discussing here an O(n^2) solution. Should you remember the problem Largest Rectangle in Histogram, you might find out its connection with this one. See the matrix below, we'll calculate the cumulated sum top-down:
[1, 0, 0, 1] => [1, 0, 0, 1]
[1, 1, 1, 0] => [2, 1, 1, 0]
[0, 0, 1, 1] => [0, 0, 2, 1]
[0, 1, 1, 1] => [0, 1, 3, 2]
If matrx[i][j] is zero, sum[i][j] = 0, otherwise sum[i][j] += matrix[i][j].
With this sum matrix, every row can be thought of as a histogram. You may use the code from that problem to calculate the maximal rectangle in the histogram. Do this for every row and you'll get the final result.
Time complexity is O(n^2), space complexity is O(n). You don't need to store the sum matrix. Instead, just updating the sum row for n times will be enough.
Accepted code:
1 // 1AC, great job! 2 class Solution { 3 public: 4 int maximalRectangle(vector<vector<char> > &matrix) { 5 int n, m; 6 7 n = (int)matrix.size(); 8 if (n == 0) { 9 return 0; 10 } 11 m = (int)matrix[0].size(); 12 if (m == 0) { 13 return 0; 14 } 15 16 vector<int> histogram; 17 18 histogram.resize(m); 19 int i, j; 20 21 for (j = 0; j < m; ++j) { 22 histogram[j] = 0; 23 } 24 25 int max_area = 0; 26 for (i = 0; i < n; ++i) { 27 for (j = 0; j < m; ++j) { 28 if (matrix[i][j] == '0') { 29 histogram[j] = 0; 30 } else { 31 histogram[j] = histogram[j] + 1; 32 } 33 } 34 max_area = max(max_area, largestRectangleArea(histogram)); 35 } 36 37 histogram.clear(); 38 return max_area; 39 } 40 private: 41 int largestRectangleArea(vector<int> &height) { 42 int i; 43 int n; 44 45 n = (int)height.size(); 46 if (n == 0) { 47 return 0; 48 } 49 50 int max_area = 0; 51 int area; 52 stack<int> st; 53 int top; 54 55 for (i = 0; i < n; ++i) { 56 if (st.empty() || height[st.top()] <= height[i]) { 57 st.push(i); 58 } else { 59 while (!st.empty() && height[st.top()] > height[i]) { 60 top = st.top(); 61 st.pop(); 62 if (st.empty()) { 63 area = i * height[top]; 64 } else { 65 area = (i - st.top() - 1) * height[top]; 66 } 67 if (area > max_area) { 68 max_area = area; 69 } 70 } 71 st.push(i); 72 } 73 } 74 while (!st.empty()) { 75 top = st.top(); 76 st.pop(); 77 if (st.empty()) { 78 area = i * height[top]; 79 } else { 80 area = (i - st.top() - 1) * height[top]; 81 } 82 if (area > max_area) { 83 max_area = area; 84 } 85 } 86 87 return max_area; 88 } 89 };