Skip to content

Commit 64b25ee

Browse files
authored
feat: add solutions to lc problem: No.1778 (doocs#2134)
No.1778.Shortest Path in a Hidden Grid
1 parent 66f8ec0 commit 64b25ee

File tree

5 files changed

+408
-216
lines changed

5 files changed

+408
-216
lines changed

solution/1700-1799/1778.Shortest Path in a Hidden Grid/README.md

+115-48
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,15 @@ The robot is initially standing on cell (1, 0), denoted by the -1.
9292

9393
**方法一:DFS 建图 + BFS 求最短路**
9494

95-
相似题目:[1810. 隐藏网格下的最小消耗路径](/solution/1800-1899/1810.Minimum%20Path%20Cost%20in%20a%20Hidden%20Grid/README.md)
95+
我们不妨假设机器人从坐标 $(0, 0)$ 出发,那么我们可以通过 DFS,找到所有可达的坐标,记录在哈希表 $vis$ 中。另外,我们还需要记录终点的坐标 $target$。
96+
97+
如果找不到终点,那么直接返回 $-1$。否则,我们可以通过 BFS,求出最短路。
98+
99+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是网格的行数和列数。
100+
101+
相似题目:
102+
103+
- [1810. 隐藏网格下的最小消耗路径](/solution/1800-1899/1810.Minimum%20Path%20Cost%20in%20a%20Hidden%20Grid/README.md)
96104

97105
<!-- tabs:start -->
98106

@@ -118,31 +126,28 @@ The robot is initially standing on cell (1, 0), denoted by the -1.
118126

119127

120128
class Solution(object):
121-
def findShortestPath(self, master: 'GridMaster') -> int:
122-
def dfs(i, j):
123-
nonlocal target
129+
def findShortestPath(self, master: "GridMaster") -> int:
130+
def dfs(i: int, j: int):
124131
if master.isTarget():
132+
nonlocal target
125133
target = (i, j)
126-
for dir, ndir, a, b in dirs:
127-
x, y = i + a, j + b
128-
if master.canMove(dir) and (x, y) not in s:
129-
s.add((x, y))
130-
master.move(dir)
134+
return
135+
for k, c in enumerate(s):
136+
x, y = i + dirs[k], j + dirs[k + 1]
137+
if master.canMove(c) and (x, y) not in vis:
138+
vis.add((x, y))
139+
master.move(c)
131140
dfs(x, y)
132-
master.move(ndir)
141+
master.move(s[(k + 2) % 4])
133142

143+
s = "URDL"
144+
dirs = (-1, 0, 1, 0, -1)
134145
target = None
135-
s = set()
136-
dirs = [
137-
['U', 'D', -1, 0],
138-
['D', 'U', 1, 0],
139-
['L', 'R', 0, -1],
140-
['R', 'L', 0, 1],
141-
]
146+
vis = set()
142147
dfs(0, 0)
143148
if target is None:
144149
return -1
145-
s.remove((0, 0))
150+
vis.discard((0, 0))
146151
q = deque([(0, 0)])
147152
ans = -1
148153
while q:
@@ -151,10 +156,10 @@ class Solution(object):
151156
i, j = q.popleft()
152157
if (i, j) == target:
153158
return ans
154-
for _, _, a, b in dirs:
159+
for a, b in pairwise(dirs):
155160
x, y = i + a, j + b
156-
if (x, y) in s:
157-
s.remove((x, y))
161+
if (x, y) in vis:
162+
vis.remove((x, y))
158163
q.append((x, y))
159164
return -1
160165
```
@@ -175,37 +180,31 @@ class Solution(object):
175180
*/
176181

177182
class Solution {
178-
private static final char[] dir = {'U', 'R', 'D', 'L'};
179-
private static final char[] ndir = {'D', 'L', 'U', 'R'};
180-
private static final int[] dirs = {-1, 0, 1, 0, -1};
181-
private static final int N = 1010;
182-
private Set<Integer> s;
183183
private int[] target;
184+
private GridMaster master;
185+
private final int n = 2010;
186+
private final String s = "URDL";
187+
private final int[] dirs = {-1, 0, 1, 0, -1};
188+
private final Set<Integer> vis = new HashSet<>();
184189

185190
public int findShortestPath(GridMaster master) {
186-
target = null;
187-
s = new HashSet<>();
188-
s.add(0);
189-
dfs(0, 0, master);
191+
this.master = master;
192+
dfs(0, 0);
190193
if (target == null) {
191194
return -1;
192195
}
193-
s.remove(0);
196+
vis.remove(0);
194197
Deque<int[]> q = new ArrayDeque<>();
195198
q.offer(new int[] {0, 0});
196-
int ans = -1;
197-
while (!q.isEmpty()) {
198-
++ans;
199-
for (int n = q.size(); n > 0; --n) {
200-
int[] p = q.poll();
201-
int i = p[0], j = p[1];
202-
if (target[0] == i && target[1] == j) {
199+
for (int ans = 0; !q.isEmpty(); ++ans) {
200+
for (int m = q.size(); m > 0; --m) {
201+
var p = q.poll();
202+
if (p[0] == target[0] && p[1] == target[1]) {
203203
return ans;
204204
}
205205
for (int k = 0; k < 4; ++k) {
206-
int x = i + dirs[k], y = j + dirs[k + 1];
207-
if (s.contains(x * N + y)) {
208-
s.remove(x * N + y);
206+
int x = p[0] + dirs[k], y = p[1] + dirs[k + 1];
207+
if (vis.remove(x * n + y)) {
209208
q.offer(new int[] {x, y});
210209
}
211210
}
@@ -214,24 +213,92 @@ class Solution {
214213
return -1;
215214
}
216215

217-
private void dfs(int i, int j, GridMaster master) {
216+
private void dfs(int i, int j) {
218217
if (master.isTarget()) {
219218
target = new int[] {i, j};
219+
return;
220220
}
221221
for (int k = 0; k < 4; ++k) {
222-
char d = dir[k], nd = ndir[k];
223222
int x = i + dirs[k], y = j + dirs[k + 1];
224-
if (master.canMove(d) && !s.contains(x * N + y)) {
225-
s.add(x * N + y);
226-
master.move(d);
227-
dfs(x, y, master);
228-
master.move(nd);
223+
if (master.canMove(s.charAt(k)) && vis.add(x * n + y)) {
224+
master.move(s.charAt(k));
225+
dfs(x, y);
226+
master.move(s.charAt((k + 2) % 4));
229227
}
230228
}
231229
}
232230
}
233231
```
234232

233+
### **C++**
234+
235+
```cpp
236+
/**
237+
* // This is the GridMaster's API interface.
238+
* // You should not implement it, or speculate about its implementation
239+
* class GridMaster {
240+
* public:
241+
* bool canMove(char direction);
242+
* void move(char direction);
243+
* boolean isTarget();
244+
* };
245+
*/
246+
247+
class Solution {
248+
private:
249+
const int n = 2010;
250+
int dirs[5] = {-1, 0, 1, 0, -1};
251+
string s = "URDL";
252+
int target;
253+
unordered_set<int> vis;
254+
255+
public:
256+
int findShortestPath(GridMaster& master) {
257+
target = n * n;
258+
vis.insert(0);
259+
dfs(0, 0, master);
260+
if (target == n * n) {
261+
return -1;
262+
}
263+
vis.erase(0);
264+
queue<pair<int, int>> q;
265+
q.emplace(0, 0);
266+
for (int ans = 0; q.size(); ++ans) {
267+
for (int m = q.size(); m; --m) {
268+
auto [i, j] = q.front();
269+
q.pop();
270+
if (i * n + j == target) {
271+
return ans;
272+
}
273+
for (int k = 0; k < 4; ++k) {
274+
int x = i + dirs[k], y = j + dirs[k + 1];
275+
if (vis.count(x * n + y)) {
276+
vis.erase(x * n + y);
277+
q.emplace(x, y);
278+
}
279+
}
280+
}
281+
}
282+
return -1;
283+
}
284+
285+
void dfs(int i, int j, GridMaster& master) {
286+
if (master.isTarget()) {
287+
target = i * n + j;
288+
}
289+
for (int k = 0; k < 4; ++k) {
290+
int x = i + dirs[k], y = j + dirs[k + 1];
291+
if (master.canMove(s[k]) && !vis.count(x * n + y)) {
292+
vis.insert(x * n + y);
293+
master.move(s[k]);
294+
dfs(x, y, master);
295+
master.move(s[(k + 2) % 4]);
296+
}
297+
}
298+
}
299+
};
300+
```
301+
235302
### **...**
236303

237304
```

0 commit comments

Comments
 (0)