Skip to content

Commit a556497

Browse files
committed
feat: add solutions to lc problem: No.3552
No.3552.Grid Teleportation Traversal
1 parent a3979f7 commit a556497

File tree

7 files changed

+744
-8
lines changed

7 files changed

+744
-8
lines changed

solution/3500-3599/3552.Grid Teleportation Traversal/README.md

+253-4
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,281 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3552.Gr
7878

7979
<!-- solution:start -->
8080

81-
### 方法一
81+
### 方法一:0-1 BFS
82+
83+
我们可以使用 0-1 BFS 来解决这个问题。我们从左上角单元格开始,使用双端队列来存储当前单元格的坐标。每次从队列中取出一个单元格,我们会检查它的四个相邻单元格,如果相邻单元格是空单元格且没有被访问过,我们就将它加入队列,并更新它的距离。
84+
85+
如果相邻单元格是一个传送门,我们就将它加入队列的前面,并更新它的距离。我们还需要维护一个字典来存储每个传送门的位置,以便在使用传送门时能够快速找到它们。
86+
87+
我们还需要一个二维数组来存储每个单元格的距离,初始值为无穷大。我们将起点的距离设置为 0,然后开始 BFS。
88+
89+
在 BFS 的过程中,我们会检查每个单元格是否是终点,如果是,就返回它的距离。如果队列为空,说明无法到达终点,返回 -1。
90+
91+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
8292

8393
<!-- tabs:start -->
8494

8595
#### Python3
8696

8797
```python
88-
98+
class Solution:
99+
def minMoves(self, matrix: List[str]) -> int:
100+
m, n = len(matrix), len(matrix[0])
101+
g = defaultdict(list)
102+
for i, row in enumerate(matrix):
103+
for j, c in enumerate(row):
104+
if c.isalpha():
105+
g[c].append((i, j))
106+
dirs = (-1, 0, 1, 0, -1)
107+
dist = [[inf] * n for _ in range(m)]
108+
dist[0][0] = 0
109+
q = deque([(0, 0)])
110+
while q:
111+
i, j = q.popleft()
112+
d = dist[i][j]
113+
if i == m - 1 and j == n - 1:
114+
return d
115+
c = matrix[i][j]
116+
if c in g:
117+
for x, y in g[c]:
118+
if d < dist[x][y]:
119+
dist[x][y] = d
120+
q.appendleft((x, y))
121+
del g[c]
122+
for a, b in pairwise(dirs):
123+
x, y = i + a, j + b
124+
if (
125+
0 <= x < m
126+
and 0 <= y < n
127+
and matrix[x][y] != "#"
128+
and d + 1 < dist[x][y]
129+
):
130+
dist[x][y] = d + 1
131+
q.append((x, y))
132+
return -1
89133
```
90134

91135
#### Java
92136

93137
```java
94-
138+
class Solution {
139+
public int minMoves(String[] matrix) {
140+
int m = matrix.length, n = matrix[0].length();
141+
Map<Character, List<int[]>> g = new HashMap<>();
142+
for (int i = 0; i < m; i++) {
143+
String row = matrix[i];
144+
for (int j = 0; j < n; j++) {
145+
char c = row.charAt(j);
146+
if (Character.isAlphabetic(c)) {
147+
g.computeIfAbsent(c, k -> new ArrayList<>()).add(new int[] {i, j});
148+
}
149+
}
150+
}
151+
int[] dirs = {-1, 0, 1, 0, -1};
152+
int INF = Integer.MAX_VALUE / 2;
153+
int[][] dist = new int[m][n];
154+
for (int[] arr : dist) Arrays.fill(arr, INF);
155+
dist[0][0] = 0;
156+
Deque<int[]> q = new ArrayDeque<>();
157+
q.add(new int[] {0, 0});
158+
while (!q.isEmpty()) {
159+
int[] cur = q.pollFirst();
160+
int i = cur[0], j = cur[1];
161+
int d = dist[i][j];
162+
if (i == m - 1 && j == n - 1) return d;
163+
char c = matrix[i].charAt(j);
164+
if (g.containsKey(c)) {
165+
for (int[] pos : g.get(c)) {
166+
int x = pos[0], y = pos[1];
167+
if (d < dist[x][y]) {
168+
dist[x][y] = d;
169+
q.addFirst(new int[] {x, y});
170+
}
171+
}
172+
g.remove(c);
173+
}
174+
for (int idx = 0; idx < 4; idx++) {
175+
int a = dirs[idx], b = dirs[idx + 1];
176+
int x = i + a, y = j + b;
177+
if (0 <= x && x < m && 0 <= y && y < n && matrix[x].charAt(y) != '#'
178+
&& d + 1 < dist[x][y]) {
179+
dist[x][y] = d + 1;
180+
q.addLast(new int[] {x, y});
181+
}
182+
}
183+
}
184+
return -1;
185+
}
186+
}
95187
```
96188

97189
#### C++
98190

99191
```cpp
100-
192+
class Solution {
193+
public:
194+
int minMoves(vector<string>& matrix) {
195+
int m = matrix.size(), n = matrix[0].size();
196+
unordered_map<char, vector<pair<int, int>>> g;
197+
for (int i = 0; i < m; ++i)
198+
for (int j = 0; j < n; ++j) {
199+
char c = matrix[i][j];
200+
if (isalpha(c)) g[c].push_back({i, j});
201+
}
202+
int dirs[5] = {-1, 0, 1, 0, -1};
203+
int INF = numeric_limits<int>::max() / 2;
204+
vector<vector<int>> dist(m, vector<int>(n, INF));
205+
dist[0][0] = 0;
206+
deque<pair<int, int>> q;
207+
q.push_back({0, 0});
208+
while (!q.empty()) {
209+
auto [i, j] = q.front();
210+
q.pop_front();
211+
int d = dist[i][j];
212+
if (i == m - 1 && j == n - 1) return d;
213+
char c = matrix[i][j];
214+
if (g.count(c)) {
215+
for (auto [x, y] : g[c])
216+
if (d < dist[x][y]) {
217+
dist[x][y] = d;
218+
q.push_front({x, y});
219+
}
220+
g.erase(c);
221+
}
222+
for (int idx = 0; idx < 4; ++idx) {
223+
int x = i + dirs[idx], y = j + dirs[idx + 1];
224+
if (0 <= x && x < m && 0 <= y && y < n && matrix[x][y] != '#' && d + 1 < dist[x][y]) {
225+
dist[x][y] = d + 1;
226+
q.push_back({x, y});
227+
}
228+
}
229+
}
230+
return -1;
231+
}
232+
};
101233
```
102234
103235
#### Go
104236
105237
```go
238+
type pair struct{ x, y int }
239+
240+
func minMoves(matrix []string) int {
241+
m, n := len(matrix), len(matrix[0])
242+
g := make(map[rune][]pair)
243+
for i := 0; i < m; i++ {
244+
for j, c := range matrix[i] {
245+
if unicode.IsLetter(c) {
246+
g[c] = append(g[c], pair{i, j})
247+
}
248+
}
249+
}
250+
dirs := []int{-1, 0, 1, 0, -1}
251+
INF := 1 << 30
252+
dist := make([][]int, m)
253+
for i := range dist {
254+
dist[i] = make([]int, n)
255+
for j := range dist[i] {
256+
dist[i][j] = INF
257+
}
258+
}
259+
dist[0][0] = 0
260+
q := list.New()
261+
q.PushBack(pair{0, 0})
262+
for q.Len() > 0 {
263+
cur := q.Remove(q.Front()).(pair)
264+
i, j := cur.x, cur.y
265+
d := dist[i][j]
266+
if i == m-1 && j == n-1 {
267+
return d
268+
}
269+
c := rune(matrix[i][j])
270+
if v, ok := g[c]; ok {
271+
for _, p := range v {
272+
x, y := p.x, p.y
273+
if d < dist[x][y] {
274+
dist[x][y] = d
275+
q.PushFront(pair{x, y})
276+
}
277+
}
278+
delete(g, c)
279+
}
280+
for idx := 0; idx < 4; idx++ {
281+
x, y := i+dirs[idx], j+dirs[idx+1]
282+
if 0 <= x && x < m && 0 <= y && y < n && matrix[x][y] != '#' && d+1 < dist[x][y] {
283+
dist[x][y] = d + 1
284+
q.PushBack(pair{x, y})
285+
}
286+
}
287+
}
288+
return -1
289+
}
290+
```
106291

292+
#### TypeScript
293+
294+
```ts
295+
function minMoves(matrix: string[]): number {
296+
const m = matrix.length,
297+
n = matrix[0].length;
298+
const g = new Map<string, [number, number][]>();
299+
for (let i = 0; i < m; i++) {
300+
for (let j = 0; j < n; j++) {
301+
const c = matrix[i][j];
302+
if (/^[A-Za-z]$/.test(c)) {
303+
if (!g.has(c)) g.set(c, []);
304+
g.get(c)!.push([i, j]);
305+
}
306+
}
307+
}
308+
309+
const dirs = [-1, 0, 1, 0, -1];
310+
const INF = Number.MAX_SAFE_INTEGER;
311+
const dist: number[][] = Array.from({ length: m }, () => Array(n).fill(INF));
312+
dist[0][0] = 0;
313+
314+
const cap = m * n * 2 + 5;
315+
const dq = new Array<[number, number]>(cap);
316+
let l = cap >> 1,
317+
r = cap >> 1;
318+
const pushFront = (v: [number, number]) => {
319+
dq[--l] = v;
320+
};
321+
const pushBack = (v: [number, number]) => {
322+
dq[r++] = v;
323+
};
324+
const popFront = (): [number, number] => dq[l++];
325+
const empty = () => l === r;
326+
327+
pushBack([0, 0]);
328+
329+
while (!empty()) {
330+
const [i, j] = popFront();
331+
const d = dist[i][j];
332+
if (i === m - 1 && j === n - 1) return d;
333+
334+
const c = matrix[i][j];
335+
if (g.has(c)) {
336+
for (const [x, y] of g.get(c)!) {
337+
if (d < dist[x][y]) {
338+
dist[x][y] = d;
339+
pushFront([x, y]);
340+
}
341+
}
342+
g.delete(c);
343+
}
344+
345+
for (let idx = 0; idx < 4; idx++) {
346+
const x = i + dirs[idx],
347+
y = j + dirs[idx + 1];
348+
if (0 <= x && x < m && 0 <= y && y < n && matrix[x][y] !== '#' && d + 1 < dist[x][y]) {
349+
dist[x][y] = d + 1;
350+
pushBack([x, y]);
351+
}
352+
}
353+
}
354+
return -1;
355+
}
107356
```
108357

109358
<!-- tabs:end -->

0 commit comments

Comments
 (0)