Skip to content

Commit 19bb84f

Browse files
authored
feat: add solutions to lc problem: No.0505 (doocs#1627)
1 parent 49bbc43 commit 19bb84f

File tree

7 files changed

+325
-204
lines changed

7 files changed

+325
-204
lines changed

solution/0500-0599/0505.The Maze II/README.md

Lines changed: 102 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@
6868

6969
<!-- 这里可写通用的实现逻辑 -->
7070

71-
BFS
71+
**方法一:BFS**
7272

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$ 分别是迷宫的行数和列数。
7480

7581
<!-- tabs:start -->
7682

@@ -84,21 +90,22 @@ class Solution:
8490
self, maze: List[List[int]], start: List[int], destination: List[int]
8591
) -> int:
8692
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)])
8997
dist = [[inf] * n for _ in range(m)]
90-
dist[rs][cs] = 0
91-
q = deque([(rs, cs)])
98+
dist[si][sj] = 0
9299
while q:
93100
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]
96103
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
100107
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]
102109
```
103110

104111
### **Java**
@@ -108,37 +115,37 @@ class Solution:
108115
```java
109116
class Solution {
110117
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;
113120
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);
116123
}
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});
120129
int[] dirs = {-1, 0, 1, 0, -1};
121130
while (!q.isEmpty()) {
122-
int[] p = q.poll();
131+
var p = q.poll();
123132
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];
127136
while (
128137
x + a >= 0 && x + a < m && y + b >= 0 && y + b < n && maze[x + a][y + b] == 0) {
129138
x += a;
130139
y += b;
131-
++step;
140+
++k;
132141
}
133-
if (step < dist[x][y]) {
134-
dist[x][y] = step;
142+
if (k < dist[x][y]) {
143+
dist[x][y] = k;
135144
q.offer(new int[] {x, y});
136145
}
137146
}
138147
}
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];
142149
}
143150
}
144151
```
@@ -149,31 +156,33 @@ class Solution {
149156
class Solution {
150157
public:
151158
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};
158168
while (!q.empty()) {
159-
auto p = q.front();
169+
auto [i, j] = q.front();
160170
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];
165174
while (x + a >= 0 && x + a < m && y + b >= 0 && y + b < n && maze[x + a][y + b] == 0) {
166175
x += a;
167176
y += b;
168-
++step;
177+
++k;
169178
}
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);
173182
}
174183
}
175184
}
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];
177186
}
178187
};
179188
```
@@ -184,34 +193,71 @@ public:
184193
func shortestDistance(maze [][]int, start []int, destination []int) int {
185194
m, n := len(maze), len(maze[0])
186195
dist := make([][]int, m)
196+
const inf = 1 << 30
187197
for i := range dist {
188198
dist[i] = make([]int, n)
189199
for j := range dist[i] {
190-
dist[i][j] = math.MaxInt32
200+
dist[i][j] = inf
191201
}
192202
}
193203
dist[start[0]][start[1]] = 0
194204
q := [][]int{start}
195-
dirs := []int{-1, 0, 1, 0, -1}
205+
dirs := [5]int{-1, 0, 1, 0, -1}
196206
for len(q) > 0 {
197-
i, j := q[0][0], q[0][1]
207+
p := q[0]
198208
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]
202213
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
204215
}
205-
if step < dist[x][y] {
206-
dist[x][y] = step
216+
if k < dist[x][y] {
217+
dist[x][y] = k
207218
q = append(q, []int{x, y})
208219
}
209220
}
210221
}
211-
if dist[destination[0]][destination[1]] == math.MaxInt32 {
222+
di, dj := destination[0], destination[1]
223+
if dist[di][dj] == inf {
212224
return -1
213225
}
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];
215261
}
216262
```
217263

0 commit comments

Comments
 (0)