-
Notifications
You must be signed in to change notification settings - Fork 21
/
221. Maximal Square.java
executable file
·135 lines (117 loc) · 4.12 KB
/
221. Maximal Square.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
M
tags: DP, Coordinate DP
time: O(mn)
space: O(mn)
只能往右边,下面走, 找面积最大的 square. 也就是找到变最长的 square.
#### DP
- 正方形, 需要每条边都是`一样长度`.
- 以右下角为考虑点, 必须满足条件: left/up/diagonal的点都是1
- 并且, 如果三个点分别都衍生向三个方向, 那么最长的 square 边就是他们之中的最短边 (受最短边限制)
- dp[i][j]: max square length when reached at (i, j), from the 3 possible directions
- dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
- init: 每个点都可能是边长1, 如果 matrix[i][j] == '1'
- Space, time O(mn)
- Rolling array: [i] 和 [i - 1] 之间的关系, 想到滚动数组优化 space, O(n) sapce.
```
/*
Given a 2D binary matrix filled with 0's and 1's, find the largest square 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: 4
*/
// dp = new int[m + 1][n + 1];
class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) return 0;
int m = matrix.length, n = matrix[0].length;
int[][] dp = new int[m + 1][n + 1];
int maxLen = 0;
// calculate
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (matrix[i - 1][j - 1] == '0') continue;
dp[i][j] = Math.min(Math.min(dp[i][j-1], dp[i-1][j]), dp[i-1][j-1]) + 1;
maxLen = Math.max(maxLen, dp[i][j]);
}
}
return maxLen * maxLen;
}
}
/*
dp = new int[m][n];
Thoughts:
Square: each border has same length.
Matrix && square problem: consider right-bottom corner.
Let dp[i][j] be the max border length, limited by points up/left/diagnal
currLength = Math.min(up, left, diagnal) + 1.
init: i = 0 row, has length = 1; j = 0 col, has length = 1.
*/
class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
int maxLen = 0;
// Init:
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = matrix[i][j] == '1' ? 1 : 0;
maxLen = Math.max(dp[i][j], maxLen);
}
}
// calculation
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
maxLen = Math.max(dp[i][j], maxLen);
}
}
}
return maxLen * maxLen;
}
}
/*
Thoughts:
[i] and [i - 1] can be used to reduce space with rolling array
*/
class Solution {
public int maximalSquare(char[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[2][n];
int maxLen = 0;
int curr = 0;
int prev = 0;
// calculation
for (int i = 0; i < m; i++) {
curr = prev;
prev = 1 - curr;
for (int j = 0; j < n; j++) {
if (i == 0 || j == 0) {
dp[curr][j] = matrix[i][j] == '1' ? 1 : 0;
maxLen = Math.max(dp[curr][j], maxLen);
continue;
}
if (matrix[i][j] == '1') {
dp[curr][j] = Math.min(Math.min(dp[prev][j], dp[curr][j - 1]), dp[prev][j - 1]) + 1;
} else {
dp[curr][j] = 0;
}
maxLen = Math.max(dp[curr][j], maxLen);
}
}
return maxLen * maxLen;
}
}
```