27
27
28
28
## 解法
29
29
30
- 此题一大误区是:遍历所有单元格,按照公式计算是否可进入,并记录可进入的方格数量。
30
+ ** 方法一:DFS + 哈希表 **
31
31
32
- 因为部分方格在公式上属于可进入,但不在机器人运动范围当中,进入一方格的前提条件是能够抵达相邻方格当中 。
32
+ 由于部分单元格不可达,因此,我们不能直接枚举所有坐标点 $(i, j)$ 进行判断,而是应该从起点 $(0, 0)$ 出发,搜索所有可达的节点,记录答案 。
33
33
34
- 而后,条件限制只能从 ` (0,0) ` 起步,对此,只需要关注方格的下方与右方即可 。
34
+ 过程中,为了避免重复搜索同一个单元格,我们可以使用数组或哈希表记录所有访问过的节点 。
35
35
36
- ** 流程** :
37
-
38
- 1 . ` (0,0) ` 开始。
39
-
40
- 2 . 根据公式判断 ` (i, j) ` 是否可进入:
41
-
42
- - 可进入,并继续往右 ` (i, j + 1) ` 往下 ` (i + 1, j) ` 重新执行流程 2。
43
- - 不可进入,退出结算。
44
-
45
- 3 . 计算可进入区域的数量,返回即可。
46
-
47
- ** 剪枝** :
48
-
49
- 对于已进入的方格,需要防止多次进入,否则会导致指数级耗时。
50
-
51
- 在确定方格可进入后,给方格加上标记。判断一个方格可进入之前,先查看是否存在对应的标记,存在标记时及时退出。
52
-
53
- 记录方式不限数组与哈希表。
36
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为方格的行数和列数。
54
37
55
38
<!-- tabs:start -->
56
39
59
42
``` python
60
43
class Solution :
61
44
def movingCount (self , m : int , n : int , k : int ) -> int :
45
+ def f (x ):
46
+ s = 0
47
+ while x:
48
+ s += x % 10
49
+ x //= 10
50
+ return s
51
+
52
+ def dfs (i , j ):
53
+ vis.add((i, j))
54
+ nonlocal ans
55
+ ans += 1
56
+ for a, b in pairwise(dirs):
57
+ x, y = i + a, j + b
58
+ if 0 <= x < m and 0 <= y < n and f(x) + f(y) <= k and (x, y) not in vis:
59
+ dfs(x, y)
60
+
61
+ vis = set ()
62
+ ans = 0
63
+ dirs = (0 , 1 , 0 )
64
+ dfs(0 , 0 )
65
+ return ans
66
+ ```
67
+
68
+ ``` python
69
+ class Solution :
70
+ def movingCount (self , m : int , n : int , k : int ) -> int :
71
+ def f (x ):
72
+ s = 0
73
+ while x:
74
+ s += x % 10
75
+ x //= 10
76
+ return s
77
+
62
78
def dfs (i , j ):
63
- if (
64
- i >= m
65
- or j >= n
66
- or vis[i][j]
67
- or (i % 10 + i // 10 + j % 10 + j // 10 ) > k
68
- ):
79
+ if not (0 <= i < m) or not (0 <= j < n) or f(i) + f(j) > k or (i, j) in vis:
69
80
return 0
70
- vis[i][j] = True
81
+ vis.add((i, j))
71
82
return 1 + dfs(i + 1 , j) + dfs(i, j + 1 )
72
83
73
- vis = [[ False ] * n for _ in range (m)]
84
+ vis = set ()
74
85
return dfs(0 , 0 )
75
86
```
76
87
77
88
### ** Java**
78
89
90
+ ``` java
91
+ class Solution {
92
+ private boolean [][] vis;
93
+ private int m;
94
+ private int n;
95
+ private int k;
96
+ private int ans;
97
+
98
+ public int movingCount (int m , int n , int k ) {
99
+ this . m = m;
100
+ this . n = n;
101
+ this . k = k;
102
+ vis = new boolean [m][n];
103
+ dfs(0 , 0 );
104
+ return ans;
105
+ }
106
+
107
+ private void dfs (int i , int j ) {
108
+ vis[i][j] = true ;
109
+ ++ ans;
110
+ int [] dirs = {1 , 0 , 1 };
111
+ for (int l = 0 ; l < 2 ; ++ l) {
112
+ int x = i + dirs[l], y = j + dirs[l + 1 ];
113
+ if (x >= 0 && x < m && y >= 0 && y < n && f(x) + f(y) <= k && ! vis[x][y]) {
114
+ dfs(x, y);
115
+ }
116
+ }
117
+ }
118
+
119
+ private int f (int x ) {
120
+ int s = 0 ;
121
+ for (; x > 0 ; x /= 10 ) {
122
+ s += x % 10 ;
123
+ }
124
+ return s;
125
+ }
126
+ }
127
+ ```
128
+
79
129
``` java
80
130
class Solution {
81
131
private boolean [][] vis;
@@ -101,30 +151,61 @@ class Solution {
101
151
}
102
152
```
103
153
104
- ### ** JavaScript **
154
+ ### ** C++ **
105
155
106
- ``` js
107
- /**
108
- * @param {number} m
109
- * @param {number} n
110
- * @param {number} k
111
- * @return {number}
112
- */
113
- var movingCount = function (m , n , k ) {
114
- const vis = new Array (m * n).fill (false );
115
- let dfs = function (i , j ) {
116
- if (
117
- i >= m ||
118
- j >= n ||
119
- vis[i * n + j] ||
120
- (i % 10 ) + Math .floor (i / 10 ) + (j % 10 ) + Math .floor (j / 10 ) > k
121
- ) {
122
- return 0 ;
123
- }
124
- vis[i * n + j] = true ;
125
- return 1 + dfs (i + 1 , j) + dfs (i, j + 1 );
126
- };
127
- return dfs (0 , 0 );
156
+ ``` cpp
157
+ class Solution {
158
+ public:
159
+ int movingCount(int m, int n, int k) {
160
+ bool vis[ m] [ n ] ;
161
+ memset(vis, false, sizeof vis);
162
+ int ans = 0;
163
+ int dirs[ 3] = {1, 0, 1};
164
+ auto f = [ ] (int x) {
165
+ int s = 0;
166
+ for (; x; x /= 10) {
167
+ s += x % 10;
168
+ }
169
+ return s;
170
+ };
171
+ function<void(int i, int j)> dfs = [ &] (int i, int j) {
172
+ vis[ i] [ j ] = true;
173
+ ++ans;
174
+ for (int l = 0; l < 2; ++l) {
175
+ int x = i + dirs[ l] , y = j + dirs[ l + 1] ;
176
+ if (x >= 0 && x < m && y >= 0 && y < n && f(x) + f(y) <= k && !vis[ x] [ y ] ) {
177
+ dfs(x, y);
178
+ }
179
+ }
180
+ };
181
+ dfs(0, 0);
182
+ return ans;
183
+ }
184
+ };
185
+ ```
186
+
187
+ ```cpp
188
+ class Solution {
189
+ public:
190
+ int movingCount(int m, int n, int k) {
191
+ bool vis[m][n];
192
+ memset(vis, false, sizeof vis);
193
+ auto f = [](int x) {
194
+ int s = 0;
195
+ for (; x; x /= 10) {
196
+ s += x % 10;
197
+ }
198
+ return s;
199
+ };
200
+ function<int(int i, int j)> dfs = [&](int i, int j) -> int {
201
+ if (i < 0 || i >= m || j < 0 || j >= n || vis[i][j] || f(i) + f(j) > k) {
202
+ return false;
203
+ }
204
+ vis[i][j] = true;
205
+ return 1 + dfs(i + 1, j) + dfs(i, j + 1);
206
+ };
207
+ return dfs(0, 0);
208
+ }
128
209
};
129
210
```
130
211
@@ -148,29 +229,60 @@ func movingCount(m int, n int, k int) int {
148
229
}
149
230
```
150
231
151
- ### ** C++**
232
+ ``` go
233
+ func movingCount (m int , n int , k int ) (ans int ) {
234
+ f := func (x int ) (s int ) {
235
+ for ; x > 0 ; x /= 10 {
236
+ s += x % 10
237
+ }
238
+ return
239
+ }
240
+ vis := make ([][]bool , m)
241
+ for i := range vis {
242
+ vis[i] = make ([]bool , n)
243
+ }
152
244
153
- ``` cpp
154
- class Solution {
155
- public:
156
- int m;
157
- int n;
158
- int k;
159
- vector<vector<bool >> vis;
245
+ dirs := [3 ]int {1 , 0 , 1 }
246
+ var dfs func (i, j int )
247
+ dfs = func (i, j int ) {
248
+ vis[i][j] = true
249
+ ans++
250
+ for l := 0 ; l < 2 ; l++ {
251
+ x , y := i+dirs[l], j+dirs[l+1 ]
252
+ if x >= 0 && x < m && y >= 0 && y < n && f (x)+f (y) <= k && !vis[x][y] {
253
+ dfs (x, y)
254
+ }
255
+ }
256
+ }
257
+ dfs (0 , 0 )
258
+ return
259
+ }
260
+ ```
160
261
161
- int movingCount(int m, int n, int k) {
162
- this->m = m;
163
- this->n = n;
164
- this->k = k;
165
- vis.resize(m, vector<bool>(n, false));
166
- return dfs(0, 0);
167
- }
262
+ ### ** JavaScript**
168
263
169
- int dfs (int i, int j) {
170
- if (i >= m || j >= n || vis[ i] [ j ] || (i % 10 + i / 10 + j % 10 + j / 10) > k) return 0;
171
- vis[ i] [ j ] = true;
264
+ ``` js
265
+ /**
266
+ * @param {number} m
267
+ * @param {number} n
268
+ * @param {number} k
269
+ * @return {number}
270
+ */
271
+ var movingCount = function (m , n , k ) {
272
+ const vis = new Array (m * n).fill (false );
273
+ let dfs = function (i , j ) {
274
+ if (
275
+ i >= m ||
276
+ j >= n ||
277
+ vis[i * n + j] ||
278
+ (i % 10 ) + Math .floor (i / 10 ) + (j % 10 ) + Math .floor (j / 10 ) > k
279
+ ) {
280
+ return 0 ;
281
+ }
282
+ vis[i * n + j] = true ;
172
283
return 1 + dfs (i + 1 , j) + dfs (i, j + 1 );
173
- }
284
+ };
285
+ return dfs (0 , 0 );
174
286
};
175
287
```
176
288
0 commit comments