@@ -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