@@ -61,16 +61,11 @@ col = 3
61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
64
- DFS。
64
+ ** 方法一: DFS**
65
65
66
- 我们设定机器人起始位置 ` (0, 0) ` ,朝向 d = 0 。
66
+ 我们不妨假设机器人的初始位置为 $ (0, 0)$,方向为 $d=0$。我们将初始位置进行打扫,并标记为已访问。然后,我们依次选择上、右、下、左四个方向进行探索,每次探索前都先判断是否已经访问过,如果没有访问过,我们就朝着该方向前进一步,然后递归探索。如果已经访问过,我们就顺时针旋转 $90^\circ$,然后继续探索下一个方向。当我们探索完所有的方向后,我们需要回到上一个位置,这时我们只需要顺时针旋转 $180^\circ$,然后前进一步,再顺时针旋转 $180^\circ$ 即可 。
67
67
68
- 将起始位置进行清扫,并进行标记(即清扫过的格子也算作障碍);然后依次选择四个朝向 up,right,down 和 left 进行深度优先搜索,相邻的两个朝向仅差一次向右旋转的操作;
69
-
70
- - 对于选择的朝向,检查下一个格子是否有障碍,如果没有,则向对应朝向移动一格,并开始新的搜索;
71
- - 如果有,则向右旋转。
72
-
73
- 如果四个朝向都搜索完毕,则回溯到上一次搜索。
68
+ 时间复杂度 $O(4^{n-m})$,空间复杂度 $O(n-m)$。其中 $n$ 和 $m$ 分别是房间的数量以及障碍物的数量。
74
69
75
70
<!-- tabs:start -->
76
71
@@ -119,26 +114,23 @@ class Solution:
119
114
:rtype: None
120
115
"""
121
116
122
- def back ():
123
- robot.turnRight()
124
- robot.turnRight()
125
- robot.move()
126
- robot.turnRight()
127
- robot.turnRight()
128
-
129
117
def dfs (i , j , d ):
130
118
vis.add((i, j))
131
119
robot.clean()
132
120
for k in range (4 ):
133
121
nd = (d + k) % 4
134
- x, y = i + dirs[nd][ 0 ] , j + dirs[nd][ 1 ]
122
+ x, y = i + dirs[nd], j + dirs[nd + 1 ]
135
123
if (x, y) not in vis and robot.move():
136
124
dfs(x, y, nd)
137
- back()
125
+ robot.turnRight()
126
+ robot.turnRight()
127
+ robot.move()
128
+ robot.turnRight()
129
+ robot.turnRight()
138
130
robot.turnRight()
139
131
132
+ dirs = (- 1 , 0 , 1 , 0 , - 1 )
140
133
vis = set ()
141
- dirs = [(- 1 , 0 ), (0 , 1 ), (1 , 0 ), (0 , - 1 )]
142
134
dfs(0 , 0 , 0 )
143
135
```
144
136
@@ -166,36 +158,32 @@ class Solution:
166
158
*/
167
159
168
160
class Solution {
169
- private Set<String > vis;
170
- private int [][] dirs = {{- 1 , 0 }, {0 , 1 }, {1 , 0 }, {0 , - 1 }};
161
+ private int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
162
+ private Set<List<Integer > > vis = new HashSet<> ();
163
+ private Robot robot;
171
164
172
165
public void cleanRoom (Robot robot ) {
173
- vis = new HashSet<> () ;
174
- dfs(0 , 0 , 0 , robot );
166
+ this . robot = robot ;
167
+ dfs(0 , 0 , 0 );
175
168
}
176
169
177
- private void dfs (int i , int j , int d , Robot robot ) {
178
- vis. add(i + " ," + j);
170
+ private void dfs (int i , int j , int d ) {
179
171
robot. clean();
172
+ vis. add(List . of(i, j));
180
173
for (int k = 0 ; k < 4 ; ++ k) {
181
174
int nd = (d + k) % 4 ;
182
- int x = i + dirs[nd][0 ];
183
- int y = j + dirs[nd][1 ];
184
- if (! vis. contains(x + " ," + y) && robot. move()) {
185
- dfs(x, y, nd, robot);
186
- back(robot);
175
+ int x = i + dirs[nd], y = j + dirs[nd + 1 ];
176
+ if (! vis. contains(List . of(x, y)) && robot. move()) {
177
+ dfs(x, y, nd);
178
+ robot. turnRight();
179
+ robot. turnRight();
180
+ robot. move();
181
+ robot. turnRight();
182
+ robot. turnRight();
187
183
}
188
184
robot. turnRight();
189
185
}
190
186
}
191
-
192
- private void back (Robot robot ) {
193
- robot. turnRight();
194
- robot. turnRight();
195
- robot. move();
196
- robot. turnRight();
197
- robot. turnRight();
198
- }
199
187
}
200
188
```
201
189
@@ -223,34 +211,27 @@ class Solution {
223
211
224
212
class Solution {
225
213
public:
226
- vector<vector<int >> dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
227
-
228
214
void cleanRoom(Robot& robot) {
229
- unordered_set<string> vis;
230
- dfs(0, 0, 0, vis, robot);
231
- }
232
-
233
- void dfs (int i, int j, int d, unordered_set<string >& vis, Robot& robot) {
234
- vis.insert(to_string(i) + "," + to_string(j));
235
- robot.clean();
236
- for (int k = 0; k < 4; ++k) {
237
- int nd = (d + k) % 4;
238
- int x = i + dirs[ nd] [ 0 ] ;
239
- int y = j + dirs[ nd] [ 1 ] ;
240
- if (!vis.count(to_string(x) + "," + to_string(y)) && robot.move()) {
241
- dfs(x, y, nd, vis, robot);
242
- back(robot);
215
+ int dirs[ 5] = {-1, 0, 1, 0, -1};
216
+ set<pair<int, int>> vis;
217
+ function<void(int, int, int)> dfs = [ &] (int i, int j, int d) {
218
+ robot.clean();
219
+ vis.insert({i, j});
220
+ for (int k = 0; k < 4; ++k) {
221
+ int nd = (d + k) % 4;
222
+ int x = i + dirs[ nd] , y = j + dirs[ nd + 1] ;
223
+ if (!vis.count({x, y}) && robot.move()) {
224
+ dfs(x, y, nd);
225
+ robot.turnRight();
226
+ robot.turnRight();
227
+ robot.move();
228
+ robot.turnRight();
229
+ robot.turnRight();
230
+ }
231
+ robot.turnRight();
243
232
}
244
- robot.turnRight();
245
- }
246
- }
247
-
248
- void back(Robot& robot) {
249
- robot.turnRight();
250
- robot.turnRight();
251
- robot.move();
252
- robot.turnRight();
253
- robot.turnRight();
233
+ };
234
+ dfs(0, 0, 0);
254
235
}
255
236
};
256
237
```
@@ -278,25 +259,22 @@ public:
278
259
*/
279
260
280
261
func cleanRoom(robot *Robot) {
281
- vis := make(map[string]bool)
282
- dirs := [][]int{{-1, 0}, {0, 1}, {1, 0}, {0, -1}}
283
- back := func() {
284
- robot.TurnRight()
285
- robot.TurnRight()
286
- robot.Move()
287
- robot.TurnRight()
288
- robot.TurnRight()
289
- }
290
- var dfs func(i, j, d int)
262
+ vis := map[[2]int]bool{}
263
+ dirs := [5]int{-1, 0, 1, 0, -1}
264
+ var dfs func(int, int, int)
291
265
dfs = func(i, j, d int) {
292
- vis[strconv.Itoa(i)+","+strconv.Itoa(j) ] = true
266
+ vis[[2]int{i, j} ] = true
293
267
robot.Clean()
294
268
for k := 0; k < 4; k++ {
295
269
nd := (d + k) % 4
296
- x, y := i+dirs[nd][0] , j+dirs[nd][ 1]
297
- if !vis[strconv.Itoa(x)+","+strconv.Itoa(y) ] && robot.Move() {
270
+ x, y := i+dirs[nd], j+dirs[nd+ 1]
271
+ if !vis[[2]int{x, y} ] && robot.Move() {
298
272
dfs(x, y, nd)
299
- back()
273
+ robot.TurnRight()
274
+ robot.TurnRight()
275
+ robot.Move()
276
+ robot.TurnRight()
277
+ robot.TurnRight()
300
278
}
301
279
robot.TurnRight()
302
280
}
@@ -305,6 +283,52 @@ func cleanRoom(robot *Robot) {
305
283
}
306
284
```
307
285
286
+ ### ** TypeScript**
287
+
288
+ ``` ts
289
+ /**
290
+ * class Robot {
291
+ * // Returns true if the cell in front is open and robot moves into the cell.
292
+ * // Returns false if the cell in front is blocked and robot stays in the current cell.
293
+ * move(): boolean {}
294
+ *
295
+ * // Robot will stay in the same cell after calling turnLeft/turnRight.
296
+ * // Each turn will be 90 degrees.
297
+ * turnRight() {}
298
+ *
299
+ * // Robot will stay in the same cell after calling turnLeft/turnRight.
300
+ * // Each turn will be 90 degrees.
301
+ * turnLeft() {}
302
+ *
303
+ * // Clean the current cell.
304
+ * clean(): {}
305
+ * }
306
+ */
307
+
308
+ function cleanRoom(robot : Robot ) {
309
+ const dirs = [- 1 , 0 , 1 , 0 , - 1 ];
310
+ const vis = new Set <string >();
311
+ const dfs = (i : number , j : number , d : number ) => {
312
+ vis .add (` ${i }-${j } ` );
313
+ robot .clean ();
314
+ for (let k = 0 ; k < 4 ; ++ k ) {
315
+ const nd = (d + k ) % 4 ;
316
+ const [x, y] = [i + dirs [nd ], j + dirs [nd + 1 ]];
317
+ if (! vis .has (` ${x }-${y } ` ) && robot .move ()) {
318
+ dfs (x , y , nd );
319
+ robot .turnRight ();
320
+ robot .turnRight ();
321
+ robot .move ();
322
+ robot .turnRight ();
323
+ robot .turnRight ();
324
+ }
325
+ robot .turnRight ();
326
+ }
327
+ };
328
+ dfs (0 , 0 , 0 );
329
+ }
330
+ ```
331
+
308
332
### ** ...**
309
333
310
334
```
0 commit comments