68
68
69
69
<!-- 这里可写通用的实现逻辑 -->
70
70
71
- BFS。
71
+ ** 方法一: BFS**
72
72
73
- 注意在一般的广度优先搜索中,我们不会经过同一个节点超过一次,但在这道题目中,只要从起始位置到当前节点的步数 step 小于之前记录的最小步数 ` dist[i, j] ` ,我们就会把 ` (i, j) ` 再次加入队列中。
73
+ 我们定义一个二维数组 $dist$,其中 $dist[ i] [ j ] $ 表示从起始位置到达 $(i,j)$ 的最短路径长度。初始时,$dist$ 中的所有元素都被初始化为一个很大的数,除了起始位置,因为起始位置到自身的距离是 $0$。
74
+
75
+ 然后,我们定义一个队列 $q$,将起始位置加入队列。随后不断进行以下操作:弹出队列中的首元素,将其四个方向上可以到达的位置加入队列中,并且在 $dist$ 中记录这些位置的距离,直到队列为空。
76
+
77
+ 最后,如果终点位置的距离仍然是一个很大的数,说明从起始位置无法到达终点位置,返回 $-1$,否则返回终点位置的距离。
78
+
79
+ 时间复杂度 $O(m \times n \times \max(m, n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是迷宫的行数和列数。
74
80
75
81
<!-- tabs:start -->
76
82
@@ -84,21 +90,22 @@ class Solution:
84
90
self , maze : List[List[int ]], start : List[int ], destination : List[int ]
85
91
) -> int :
86
92
m, n = len (maze), len (maze[0 ])
87
- rs, cs = start
88
- rd, cd = destination
93
+ dirs = (- 1 , 0 , 1 , 0 , - 1 )
94
+ si, sj = start
95
+ di, dj = destination
96
+ q = deque([(si, sj)])
89
97
dist = [[inf] * n for _ in range (m)]
90
- dist[rs][cs] = 0
91
- q = deque([(rs, cs)])
98
+ dist[si][sj] = 0
92
99
while q:
93
100
i, j = q.popleft()
94
- for a, b in [[ 0 , - 1 ], [ 0 , 1 ], [ 1 , 0 ], [ - 1 , 0 ]] :
95
- x, y, step = i, j, dist[i][j]
101
+ for a, b in pairwise(dirs) :
102
+ x, y, k = i, j, dist[i][j]
96
103
while 0 <= x + a < m and 0 <= y + b < n and maze[x + a][y + b] == 0 :
97
- x, y, step = x + a, y + b, step + 1
98
- if step < dist[x][y]:
99
- dist[x][y] = step
104
+ x, y, k = x + a, y + b, k + 1
105
+ if k < dist[x][y]:
106
+ dist[x][y] = k
100
107
q.append((x, y))
101
- return - 1 if dist[rd][cd ] == inf else dist[rd][cd ]
108
+ return - 1 if dist[di][dj ] == inf else dist[di][dj ]
102
109
```
103
110
104
111
### ** Java**
@@ -108,37 +115,37 @@ class Solution:
108
115
``` java
109
116
class Solution {
110
117
public int shortestDistance (int [][] maze , int [] start , int [] destination ) {
111
- int m = maze. length;
112
- int n = maze[ 0 ] . length ;
118
+ int m = maze. length, n = maze[ 0 ] . length ;
119
+ final int inf = 1 << 30 ;
113
120
int [][] dist = new int [m][n];
114
- for (int i = 0 ; i < m; ++ i ) {
115
- Arrays . fill(dist[i], Integer . MAX_VALUE );
121
+ for (var row : dist ) {
122
+ Arrays . fill(row, inf );
116
123
}
117
- dist[start[0 ]][start[1 ]] = 0 ;
118
- Deque<int[]> q = new LinkedList<> ();
119
- q. offer(start);
124
+ int si = start[0 ], sj = start[1 ];
125
+ int di = destination[0 ], dj = destination[1 ];
126
+ dist[si][sj] = 0 ;
127
+ Deque<int[]> q = new ArrayDeque<> ();
128
+ q. offer(new int [] {si, sj});
120
129
int [] dirs = {- 1 , 0 , 1 , 0 , - 1 };
121
130
while (! q. isEmpty()) {
122
- int [] p = q. poll();
131
+ var p = q. poll();
123
132
int i = p[0 ], j = p[1 ];
124
- for (int k = 0 ; k < 4 ; ++ k ) {
125
- int x = i, y = j, step = dist[i][j];
126
- int a = dirs[k ], b = dirs[k + 1 ];
133
+ for (int d = 0 ; d < 4 ; ++ d ) {
134
+ int x = i, y = j, k = dist[i][j];
135
+ int a = dirs[d ], b = dirs[d + 1 ];
127
136
while (
128
137
x + a >= 0 && x + a < m && y + b >= 0 && y + b < n && maze[x + a][y + b] == 0 ) {
129
138
x += a;
130
139
y += b;
131
- ++ step ;
140
+ ++ k ;
132
141
}
133
- if (step < dist[x][y]) {
134
- dist[x][y] = step ;
142
+ if (k < dist[x][y]) {
143
+ dist[x][y] = k ;
135
144
q. offer(new int [] {x, y});
136
145
}
137
146
}
138
147
}
139
- return dist[destination[0 ]][destination[1 ]] == Integer . MAX_VALUE
140
- ? - 1
141
- : dist[destination[0 ]][destination[1 ]];
148
+ return dist[di][dj] == inf ? - 1 : dist[di][dj];
142
149
}
143
150
}
144
151
```
@@ -149,31 +156,33 @@ class Solution {
149
156
class Solution {
150
157
public:
151
158
int shortestDistance(vector<vector<int >>& maze, vector<int >& start, vector<int >& destination) {
152
- int m = maze.size();
153
- int n = maze[ 0] .size();
154
- vector<vector<int >> dist(m, vector<int >(n, INT_MAX));
155
- dist[ start[ 0]] [ start[ 1]] = 0;
156
- queue<vector<int >> q{{start}};
157
- vector<int > dirs = {-1, 0, 1, 0, -1};
159
+ int m = maze.size(), n = maze[ 0] .size();
160
+ int dist[ m] [ n ] ;
161
+ memset(dist, 0x3f, sizeof(dist));
162
+ int si = start[ 0] , sj = start[ 1] ;
163
+ int di = destination[ 0] , dj = destination[ 1] ;
164
+ dist[ si] [ sj ] = 0;
165
+ queue<pair<int, int>> q;
166
+ q.emplace(si, sj);
167
+ int dirs[ 5] = {-1, 0, 1, 0, -1};
158
168
while (!q.empty()) {
159
- auto p = q.front();
169
+ auto [ i, j ] = q.front();
160
170
q.pop();
161
- int i = p[ 0] , j = p[ 1] ;
162
- for (int k = 0; k < 4; ++k) {
163
- int x = i, y = j, step = dist[ i] [ j ] ;
164
- int a = dirs[ k] , b = dirs[ k + 1] ;
171
+ for (int d = 0; d < 4; ++d) {
172
+ int x = i, y = j, k = dist[ i] [ j ] ;
173
+ int a = dirs[ d] , b = dirs[ d + 1] ;
165
174
while (x + a >= 0 && x + a < m && y + b >= 0 && y + b < n && maze[ x + a] [ y + b ] == 0) {
166
175
x += a;
167
176
y += b;
168
- ++step ;
177
+ ++k ;
169
178
}
170
- if (step < dist[ x] [ y ] ) {
171
- dist[ x] [ y ] = step ;
172
- q.push({ x, y} );
179
+ if (k < dist[ x] [ y ] ) {
180
+ dist[ x] [ y ] = k ;
181
+ q.emplace( x, y);
173
182
}
174
183
}
175
184
}
176
- return dist[ destination [ 0 ]] [ destination [ 1 ]] == INT_MAX ? -1 : dist[ destination [ 0 ]] [ destination [ 1 ] ] ;
185
+ return dist[ di ] [ dj ] == 0x3f3f3f3f ? -1 : dist[ di ] [ dj ] ;
177
186
}
178
187
};
179
188
```
@@ -184,34 +193,71 @@ public:
184
193
func shortestDistance(maze [][]int, start []int, destination []int) int {
185
194
m, n := len(maze), len(maze[0])
186
195
dist := make([][]int, m)
196
+ const inf = 1 << 30
187
197
for i := range dist {
188
198
dist[i] = make([]int, n)
189
199
for j := range dist[i] {
190
- dist[i][j] = math.MaxInt32
200
+ dist[i][j] = inf
191
201
}
192
202
}
193
203
dist[start[0]][start[1]] = 0
194
204
q := [][]int{start}
195
- dirs := []int{-1, 0, 1, 0, -1}
205
+ dirs := [5 ]int{-1, 0, 1, 0, -1}
196
206
for len(q) > 0 {
197
- i, j := q[0][0], q[0][1 ]
207
+ p := q[0]
198
208
q = q[1:]
199
- for k := 0; k < 4; k++ {
200
- x, y, step := i, j, dist[i][j]
201
- a, b := dirs[k], dirs[k+1]
209
+ i, j := p[0], p[1]
210
+ for d := 0; d < 4; d++ {
211
+ x, y, k := i, j, dist[i][j]
212
+ a, b := dirs[d], dirs[d+1]
202
213
for x+a >= 0 && x+a < m && y+b >= 0 && y+b < n && maze[x+a][y+b] == 0 {
203
- x, y, step = x+a, y+b, step +1
214
+ x, y, k = x+a, y+b, k +1
204
215
}
205
- if step < dist[x][y] {
206
- dist[x][y] = step
216
+ if k < dist[x][y] {
217
+ dist[x][y] = k
207
218
q = append(q, []int{x, y})
208
219
}
209
220
}
210
221
}
211
- if dist[destination[0]][destination[1]] == math.MaxInt32 {
222
+ di, dj := destination[0], destination[1]
223
+ if dist[di][dj] == inf {
212
224
return -1
213
225
}
214
- return dist[destination[0]][destination[1]]
226
+ return dist[di][dj]
227
+ }
228
+ ```
229
+
230
+ ### ** TypeScript**
231
+
232
+ ``` ts
233
+ function shortestDistance(maze : number [][], start : number [], destination : number []): number {
234
+ const m = maze .length ;
235
+ const n = maze [0 ].length ;
236
+ const dist: number [][] = Array .from ({ length: m }, () =>
237
+ Array .from ({ length: n }, () => Infinity ),
238
+ );
239
+ const [si, sj] = start ;
240
+ const [di, dj] = destination ;
241
+ dist [si ][sj ] = 0 ;
242
+ const q: number [][] = [[si , sj ]];
243
+ const dirs = [- 1 , 0 , 1 , 0 , - 1 ];
244
+ while (q .length ) {
245
+ const [i, j] = q .shift ()! ;
246
+ for (let d = 0 ; d < 4 ; ++ d ) {
247
+ let [x, y, k] = [i , j , dist [i ][j ]];
248
+ const [a, b] = [dirs [d ], dirs [d + 1 ]];
249
+ while (x + a >= 0 && x + a < m && y + b >= 0 && y + b < n && maze [x + a ][y + b ] === 0 ) {
250
+ x += a ;
251
+ y += b ;
252
+ ++ k ;
253
+ }
254
+ if (k < dist [x ][y ]) {
255
+ dist [x ][y ] = k ;
256
+ q .push ([x , y ]);
257
+ }
258
+ }
259
+ }
260
+ return dist [di ][dj ] === Infinity ? - 1 : dist [di ][dj ];
215
261
}
216
262
```
217
263
0 commit comments