33
33
  ; [0,1,1,1]
34
34
]
35
35
<strong >输出:</strong >15
36
- <strong >解释:</strong >
36
+ <strong >解释:</strong >
37
37
边长为 1 的正方形有 <strong >10</strong > 个。
38
38
边长为 2 的正方形有 <strong >4</strong > 个。
39
39
边长为 3 的正方形有 <strong >1</strong > 个。
@@ -42,15 +42,15 @@ tags:
42
42
43
43
<p ><strong >示例 2:</strong ></p >
44
44
45
- <pre ><strong >输入:</strong >matrix =
45
+ <pre ><strong >输入:</strong >matrix =
46
46
[
47
47
[1,0,1],
48
48
[1,1,0],
49
49
[1,1,0]
50
50
]
51
51
<strong >输出:</strong >7
52
52
<strong >解释:</strong >
53
- 边长为 1 的正方形有 <strong >6</strong > 个。
53
+ 边长为 1 的正方形有 <strong >6</strong > 个。
54
54
边长为 2 的正方形有 <strong >1</strong > 个。
55
55
正方形的总数 = 6 + 1 = <strong >7</strong >.
56
56
</pre >
71
71
72
72
<!-- solution:start -->
73
73
74
- ### 方法一
74
+ ### 方法一:动态规划
75
+
76
+ 我们定义 $f[ i] [ j ] $ 为以 $(i,j)$ 为右下角的正方形子矩阵的边长,初始时 $f[ i] [ j ] = 0$,答案为 $\sum_ {i,j} f[ i] [ j ] $。
77
+
78
+ 考虑 $f[ i] [ j ] $ 如何进行状态转移。
79
+
80
+ - 当 $\text{matrix}[ i] [ j ] = 0$ 时,有 $f[ i] [ j ] = 0$。
81
+ - 当 $\text{matrix}[ i] [ j ] = 1$ 时,状态 $f[ i] [ j ] $ 的值取决于其上、左、左上三个位置的值:
82
+ - 如果 $i = 0$ 或 $j = 0$,则 $f[ i] [ j ] = 1$。
83
+ - 否则 $f[ i] [ j ] = \min(f[ i-1] [ j-1 ] , f[ i-1] [ j ] , f[ i] [ j-1 ] ) + 1$。
84
+
85
+ 答案为 $\sum_ {i,j} f[ i] [ j ] $。
86
+
87
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数。
75
88
76
89
<!-- tabs:start -->
77
90
@@ -133,11 +146,14 @@ public:
133
146
vector<vector<int >> f(m, vector<int >(n));
134
147
for (int i = 0; i < m; ++i) {
135
148
for (int j = 0; j < n; ++j) {
136
- if (matrix[ i] [ j ] == 0) continue;
137
- if (i == 0 || j == 0)
149
+ if (matrix[ i] [ j ] == 0) {
150
+ continue;
151
+ }
152
+ if (i == 0 || j == 0) {
138
153
f[ i] [ j ] = 1;
139
- else
154
+ } else {
140
155
f[ i] [ j ] = min(f[ i - 1] [ j - 1 ] , min(f[ i - 1] [ j ] , f[ i] [ j - 1 ] )) + 1;
156
+ }
141
157
ans += f[ i] [ j ] ;
142
158
}
143
159
}
@@ -176,45 +192,115 @@ func countSquares(matrix [][]int) int {
176
192
177
193
``` ts
178
194
function countSquares(matrix : number [][]): number {
179
- const [m, n] = [matrix .length , matrix [0 ].length ];
180
- const f = Array .from ({ length: m }, () => Array (n ));
181
- const dfs = (i : number , j : number ): number => {
182
- if (i === m || j === n || ! matrix [i ][j ]) return 0 ;
183
- f [i ][j ] ?? = 1 + Math .min (dfs (i + 1 , j ), dfs (i , j + 1 ), dfs (i + 1 , j + 1 ));
184
- return f [i ][j ];
185
- };
195
+ const m = matrix .length ;
196
+ const n = matrix [0 ].length ;
197
+ const f: number [][] = Array .from ({ length: m }, () => Array (n ).fill (0 ));
186
198
let ans = 0 ;
187
199
188
200
for (let i = 0 ; i < m ; i ++ ) {
189
201
for (let j = 0 ; j < n ; j ++ ) {
190
- ans += dfs (i , j );
202
+ if (matrix [i ][j ] === 0 ) {
203
+ continue ;
204
+ }
205
+ if (i === 0 || j === 0 ) {
206
+ f [i ][j ] = 1 ;
207
+ } else {
208
+ f [i ][j ] = Math .min (f [i - 1 ][j - 1 ], Math .min (f [i - 1 ][j ], f [i ][j - 1 ])) + 1 ;
209
+ }
210
+ ans += f [i ][j ];
191
211
}
192
212
}
193
213
194
214
return ans ;
195
215
}
196
216
```
197
217
218
+ #### Rust
219
+
220
+ ``` rust
221
+ impl Solution {
222
+ pub fn count_squares (matrix : Vec <Vec <i32 >>) -> i32 {
223
+ let m = matrix . len ();
224
+ let n = matrix [0 ]. len ();
225
+ let mut f = vec! [vec! [0 ; n ]; m ];
226
+ let mut ans = 0 ;
227
+
228
+ for i in 0 .. m {
229
+ for j in 0 .. n {
230
+ if matrix [i ][j ] == 0 {
231
+ continue ;
232
+ }
233
+ if i == 0 || j == 0 {
234
+ f [i ][j ] = 1 ;
235
+ } else {
236
+ f [i ][j ] = std :: cmp :: min (f [i - 1 ][j - 1 ], std :: cmp :: min (f [i - 1 ][j ], f [i ][j - 1 ])) + 1 ;
237
+ }
238
+ ans += f [i ][j ];
239
+ }
240
+ }
241
+
242
+ ans
243
+ }
244
+ }
245
+ ```
246
+
198
247
#### JavaScript
199
248
200
249
``` js
201
- function countSquares ( matrix ) {
202
- const [ m , n ] = [ matrix . length , matrix[ 0 ]. length ];
203
- const f = Array . from ({ length : m }, () => Array (n));
204
- const dfs = ( i , j ) => {
205
- if (i === m || j === n || ! matrix[i][j]) return 0 ;
206
- f[i][j] ?? = 1 + Math . min ( dfs (i + 1 , j), dfs (i, j + 1 ), dfs (i + 1 , j + 1 )) ;
207
- return f[i][j] ;
208
- } ;
250
+ /**
251
+ * @param {number[][]} matrix
252
+ * @return {number}
253
+ */
254
+ var countSquares = function ( matrix ) {
255
+ const m = matrix . length ;
256
+ const n = matrix[ 0 ]. length ;
257
+ const f = Array . from ({ length : m }, () => Array (n). fill ( 0 )) ;
209
258
let ans = 0 ;
210
259
211
260
for (let i = 0 ; i < m; i++ ) {
212
261
for (let j = 0 ; j < n; j++ ) {
213
- ans += dfs (i, j);
262
+ if (matrix[i][j] === 0 ) {
263
+ continue ;
264
+ }
265
+ if (i === 0 || j === 0 ) {
266
+ f[i][j] = 1 ;
267
+ } else {
268
+ f[i][j] = Math .min (f[i - 1 ][j - 1 ], Math .min (f[i - 1 ][j], f[i][j - 1 ])) + 1 ;
269
+ }
270
+ ans += f[i][j];
214
271
}
215
272
}
216
273
217
274
return ans;
275
+ };
276
+ ```
277
+
278
+ #### C#
279
+
280
+ ``` cs
281
+ public class Solution {
282
+ public int CountSquares (int [][] matrix ) {
283
+ int m = matrix .Length ;
284
+ int n = matrix [0 ].Length ;
285
+ int [,] f = new int [m , n ];
286
+ int ans = 0 ;
287
+
288
+ for (int i = 0 ; i < m ; i ++ ) {
289
+ for (int j = 0 ; j < n ; j ++ ) {
290
+ if (matrix [i ][j ] == 0 ) {
291
+ continue ;
292
+ }
293
+ if (i == 0 || j == 0 ) {
294
+ f [i , j ] = 1 ;
295
+ } else {
296
+ f [i , j ] = Math .Min (f [i - 1 , j - 1 ], Math .Min (f [i - 1 , j ], f [i , j - 1 ])) + 1 ;
297
+ }
298
+ ans += f [i , j ];
299
+ }
300
+ }
301
+
302
+ return ans ;
303
+ }
218
304
}
219
305
```
220
306
0 commit comments