Skip to content

Commit cfe3e3c

Browse files
authored
feat: add solutions to lc problem: No.0489 (doocs#1582)
No.0489.Robot Room Cleaner
1 parent 4435fac commit cfe3e3c

File tree

10 files changed

+406
-329
lines changed

10 files changed

+406
-329
lines changed

solution/0400-0499/0489.Robot Room Cleaner/README.md

Lines changed: 101 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,11 @@ col = 3
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64-
DFS
64+
**方法一:DFS**
6565

66-
我们设定机器人起始位置 `(0, 0)`,朝向 d = 0
66+
我们不妨假设机器人的初始位置为 $(0, 0)$,方向为 $d=0$。我们将初始位置进行打扫,并标记为已访问。然后,我们依次选择上、右、下、左四个方向进行探索,每次探索前都先判断是否已经访问过,如果没有访问过,我们就朝着该方向前进一步,然后递归探索。如果已经访问过,我们就顺时针旋转 $90^\circ$,然后继续探索下一个方向。当我们探索完所有的方向后,我们需要回到上一个位置,这时我们只需要顺时针旋转 $180^\circ$,然后前进一步,再顺时针旋转 $180^\circ$ 即可
6767

68-
将起始位置进行清扫,并进行标记(即清扫过的格子也算作障碍);然后依次选择四个朝向 up,right,down 和 left 进行深度优先搜索,相邻的两个朝向仅差一次向右旋转的操作;
69-
70-
- 对于选择的朝向,检查下一个格子是否有障碍,如果没有,则向对应朝向移动一格,并开始新的搜索;
71-
- 如果有,则向右旋转。
72-
73-
如果四个朝向都搜索完毕,则回溯到上一次搜索。
68+
时间复杂度 $O(4^{n-m})$,空间复杂度 $O(n-m)$。其中 $n$ 和 $m$ 分别是房间的数量以及障碍物的数量。
7469

7570
<!-- tabs:start -->
7671

@@ -119,26 +114,23 @@ class Solution:
119114
:rtype: None
120115
"""
121116

122-
def back():
123-
robot.turnRight()
124-
robot.turnRight()
125-
robot.move()
126-
robot.turnRight()
127-
robot.turnRight()
128-
129117
def dfs(i, j, d):
130118
vis.add((i, j))
131119
robot.clean()
132120
for k in range(4):
133121
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]
135123
if (x, y) not in vis and robot.move():
136124
dfs(x, y, nd)
137-
back()
125+
robot.turnRight()
126+
robot.turnRight()
127+
robot.move()
128+
robot.turnRight()
129+
robot.turnRight()
138130
robot.turnRight()
139131

132+
dirs = (-1, 0, 1, 0, -1)
140133
vis = set()
141-
dirs = [(-1, 0), (0, 1), (1, 0), (0, -1)]
142134
dfs(0, 0, 0)
143135
```
144136

@@ -166,36 +158,32 @@ class Solution:
166158
*/
167159

168160
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;
171164

172165
public void cleanRoom(Robot robot) {
173-
vis = new HashSet<>();
174-
dfs(0, 0, 0, robot);
166+
this.robot = robot;
167+
dfs(0, 0, 0);
175168
}
176169

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) {
179171
robot.clean();
172+
vis.add(List.of(i, j));
180173
for (int k = 0; k < 4; ++k) {
181174
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();
187183
}
188184
robot.turnRight();
189185
}
190186
}
191-
192-
private void back(Robot robot) {
193-
robot.turnRight();
194-
robot.turnRight();
195-
robot.move();
196-
robot.turnRight();
197-
robot.turnRight();
198-
}
199187
}
200188
```
201189

@@ -223,34 +211,27 @@ class Solution {
223211

224212
class Solution {
225213
public:
226-
vector<vector<int>> dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
227-
228214
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();
243232
}
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);
254235
}
255236
};
256237
```
@@ -278,25 +259,22 @@ public:
278259
*/
279260
280261
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)
291265
dfs = func(i, j, d int) {
292-
vis[strconv.Itoa(i)+","+strconv.Itoa(j)] = true
266+
vis[[2]int{i, j}] = true
293267
robot.Clean()
294268
for k := 0; k < 4; k++ {
295269
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() {
298272
dfs(x, y, nd)
299-
back()
273+
robot.TurnRight()
274+
robot.TurnRight()
275+
robot.Move()
276+
robot.TurnRight()
277+
robot.TurnRight()
300278
}
301279
robot.TurnRight()
302280
}
@@ -305,6 +283,52 @@ func cleanRoom(robot *Robot) {
305283
}
306284
```
307285

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+
308332
### **...**
309333

310334
```

0 commit comments

Comments
 (0)