LeetCode Online Judge 题目C# 练习 - Maximal Rectangle
Given a 2D matrix fill with 0's and 1's, find the largest rectangle containing all ones and return its area.
1 public static int MaximalRectangle(List<List<char>> matrix) 2 { 3 int n = matrix.Count; 4 int m = matrix[0].Count; 5 int curr_area = 0; 6 int max_area = 0; 7 8 for (int i = 0; i < n; i++) 9 { 10 for (int j = 0; j < m; j++) 11 { 12 if(matrix[i][j] == '1') 13 { 14 int lastj = m; 15 for (int k = i; k < n && matrix[k][j] == '1'; k++) 16 { 17 for (int l = j; l < lastj; l++) 18 { 19 if (matrix[k][l] == '1') 20 { 21 curr_area = (l - j + 1) * (k - i + 1); 22 max_area = Math.Max(max_area, curr_area); 23 } 24 else 25 lastj = l; 26 } 27 } 28 } 29 } 30 } 31 32 return max_area; 33 }
代码分析:
Brute Force, O(n4). 每一个是1的格子,都从上至下,从左往右,去看最大面积。lastj变量是存放最小的列。
例如:
1 | 1 | 0 | 1 |
1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 |
0 | 0 | 1 | 1 |
[0,0] : 第一行: curr_area: 2, max_area: 2, lastj = 2
第二行: curr_area: 2, max_area: 2, lastj = 1
第三行: curr_area: 3, max_area: 3, lastj = 1
max_area = 3;
...
1 public static int MaximalRectangleOpt(List<List<char>> matrix) 2 { 3 int n = matrix.Count; 4 int m = matrix[0].Count; 5 int[,] dp = new int[n, m]; 6 int curr_area = 0; 7 int max_area = 0; 8 9 for (int i = 0; i < n; i++) 10 { 11 for (int j = 0; j < m; j++) 12 { 13 if (matrix[i][j] == '1') 14 dp[i, j] = j > 0 ? dp[i, j - 1] + 1 : 1; 15 else 16 dp[i, j] = 0; 17 } 18 } 19 20 for (int i = 0; i < n; i++) 21 { 22 for (int j = 0; j < m; j++) 23 { 24 int k = i; 25 int min = dp[i, j]; 26 while (k >= 0 && dp[k,j] > 0) 27 { 28 min = Math.Min(min, dp[k, j]); 29 curr_area = min * (i - k + 1); 30 max_area = Math.Max(max_area, curr_area); 31 k--; 32 } 33 } 34 } 35 36 return max_area; 37 }
代码分析:
利用DP,第一次n2循环,先预处理。然后再O(n3)计算最大面积。
例如:
1 | 1 | 0 | 1 |
1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 |
0 | 0 | 1 | 1 |
DP处理后生成新的2D- array
1 | 2 | 0 | 1 |
1 | 0 | 1 | 2 |
1 | 2 | 3 | 4 |
0 | 0 | 1 | 2 |
每个格子相应的最大面积
1 | 2 | 0 | 1 |
2 | 0 | 1 | 2 |
3 | 2 | 3 | 4 |
0 | 0 | 3 | 6 |