Description
Given a 2D binary matrix filled with 0’s and 1’s, find the largest rectangle containing only 1’s and return its area.
Example:
Input:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
Output: 6
Solution
给一个二维char数组,找到由‘1’组成的最大的正方形面积。
Using dynamic programming to solve this problem. We use three arrays left, right and height to perfrom dp row by row.
height[] document the height of this position, if it is ‘1’ height[j]++.
left[] stores the left consecutive ‘1’ start position(inclusive), using curLeft to denote this iteration’s ‘1’'s position, compare with last row, find max one(because it is compare with 0, if last row does not have 1). or we should set it to initial value 0 and move curLeft forward.
right[] stores the right consecutive ‘1’ start position(exclusive), using curRight to denote this iteration’s ‘1’'s position, compare with last row, find min one(because it is compare with n, if last row does not have 1). Or we should set it to initial value n and curRIght = n;
After that, compute area one by one and compare with res.
Code
class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
return 0;
}
int m = matrix.length, n = matrix[0].length;
int[] left = new int[n], right = new int[n], height = new int[n];
Arrays.fill(right, n);
int res = 0;
for (int i = 0; i < m; i++){
int curLeft = 0, curRight = n;
for (int j = 0; j < n; j++){
if (matrix[i][j] == '1'){
height[j]++;
}
else{
height[j] = 0;
}
}
for (int j = 0; j < n; j++){
if (matrix[i][j] == '1'){
left[j] = Math.max(left[j], curLeft);
}
else{
left[j] = 0;
curLeft = j + 1;
}
}
for (int j = n - 1; j >= 0; j--){
if (matrix[i][j] == '1'){
right[j] = Math.min(right[j], curRight);
}
else{
right[j] = n;
curRight = j;
}
}
for (int j = 0; j < n; j++){
res = Math.max(res, (right[j] - left[j]) * height[j]);
}
}
return res;
}
}
Time Complexity: O(mn)
Space Complexity: O(n)
Review
We could speed up by using two iteration.
class Solution {
public int maximalRectangle(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
return 0;
}
int m = matrix.length, n = matrix[0].length;
int[] left = new int[n], right = new int[n], height = new int[n];
Arrays.fill(right, n);
int res = 0;
for (int i = 0; i < m; i++){
int curLeft = 0, curRight = n;
for (int j = 0; j < n; j++){
if (matrix[i][j] == '1'){
height[j]++;
left[j] = Math.max(left[j], curLeft);
}
else{
height[j] = 0;
left[j] = 0;
curLeft = j + 1;
}
int k = n - 1 - j;
if (matrix[i][k] == '1'){
right[k] = Math.min(right[k], curRight);
}
else{
right[k] = n;
curRight = k;
}
}
for (int j = 0; j < n; j++){
res = Math.max(res, (right[j] - left[j]) * height[j]);
}
}
return res;
}
}