Skip to content

Commit bc563da

Browse files
authored
feat: add solutions to lc problem: No.0909 (#3261)
No.0909.Snakes and Ladders
1 parent d273d27 commit bc563da

File tree

7 files changed

+338
-268
lines changed

7 files changed

+338
-268
lines changed

solution/0900-0999/0909.Snakes and Ladders/README.md

+118-89
Original file line numberDiff line numberDiff line change
@@ -88,35 +88,44 @@ tags:
8888

8989
### 方法一:BFS
9090

91+
我们可以使用广度优先搜索的方法,从起点开始,每次向前走 1 到 6 步,然后判断是否有蛇或梯子,如果有,就走到蛇或梯子的目的地,否则就走到下一个方格。
92+
93+
具体地,我们使用一个队列 $\textit{q}$ 来存储当前可以到达的方格编号,初始时将编号 $1$ 放入队列。同时我们使用一个集合 $\textit{vis}$ 来记录已经到达过的方格,避免重复访问,初始时将编号 $1$ 加入集合 $\textit{vis}$。
94+
95+
在每一次的操作中,我们取出队首的方格编号 $x$,如果 $x$ 是终点,那么我们就可以返回当前的步数。否则我们将 $x$ 向前走 $1$ 到 $6$ 步,设新的编号为 $y$,如果 $y$ 落在棋盘外,那么我们就直接跳过。否则,我们需要找到 $y$ 对应的行和列,由于行的编号是从下到上递减的,而列的编号与行的奇偶性有关,因此我们需要进行一些计算得到 $y$ 对应的行和列。
96+
97+
如果 $y$ 对应的方格上有蛇或梯子,那么我们需要额外走到蛇或梯子的目的地,设其为 $z$。如果 $z$ 没有被访问过,我们就将 $z$ 加入队列和集合中,这样我们就可以继续进行广度优先搜索。
98+
99+
如果我们最终无法到达终点,那么我们就返回 $-1$。
100+
101+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是棋盘的边长。
102+
91103
<!-- tabs:start -->
92104

93105
#### Python3
94106

95107
```python
96108
class Solution:
97109
def snakesAndLadders(self, board: List[List[int]]) -> int:
98-
def get(x):
99-
i, j = (x - 1) // n, (x - 1) % n
100-
if i & 1:
101-
j = n - 1 - j
102-
return n - 1 - i, j
103-
104110
n = len(board)
105111
q = deque([1])
106112
vis = {1}
107113
ans = 0
114+
m = n * n
108115
while q:
109116
for _ in range(len(q)):
110-
curr = q.popleft()
111-
if curr == n * n:
117+
x = q.popleft()
118+
if x == m:
112119
return ans
113-
for next in range(curr + 1, min(curr + 7, n * n + 1)):
114-
i, j = get(next)
115-
if board[i][j] != -1:
116-
next = board[i][j]
117-
if next not in vis:
118-
q.append(next)
119-
vis.add(next)
120+
for y in range(x + 1, min(x + 6, m) + 1):
121+
i, j = divmod(y - 1, n)
122+
if i & 1:
123+
j = n - j - 1
124+
i = n - i - 1
125+
z = y if board[i][j] == -1 else board[i][j]
126+
if z not in vis:
127+
vis.add(z)
128+
q.append(z)
120129
ans += 1
121130
return -1
122131
```
@@ -125,46 +134,35 @@ class Solution:
125134

126135
```java
127136
class Solution {
128-
private int n;
129-
130137
public int snakesAndLadders(int[][] board) {
131-
n = board.length;
138+
int n = board.length;
132139
Deque<Integer> q = new ArrayDeque<>();
133140
q.offer(1);
134-
boolean[] vis = new boolean[n * n + 1];
141+
int m = n * n;
142+
boolean[] vis = new boolean[m + 1];
135143
vis[1] = true;
136-
int ans = 0;
137-
while (!q.isEmpty()) {
138-
for (int t = q.size(); t > 0; --t) {
139-
int curr = q.poll();
140-
if (curr == n * n) {
144+
for (int ans = 0; !q.isEmpty(); ++ans) {
145+
for (int k = q.size(); k > 0; --k) {
146+
int x = q.poll();
147+
if (x == m) {
141148
return ans;
142149
}
143-
for (int k = curr + 1; k <= Math.min(curr + 6, n * n); ++k) {
144-
int[] p = get(k);
145-
int next = k;
146-
int i = p[0], j = p[1];
147-
if (board[i][j] != -1) {
148-
next = board[i][j];
150+
for (int y = x + 1; y <= Math.min(x + 6, m); ++y) {
151+
int i = (y - 1) / n, j = (y - 1) % n;
152+
if (i % 2 == 1) {
153+
j = n - j - 1;
149154
}
150-
if (!vis[next]) {
151-
vis[next] = true;
152-
q.offer(next);
155+
i = n - i - 1;
156+
int z = board[i][j] == -1 ? y : board[i][j];
157+
if (!vis[z]) {
158+
vis[z] = true;
159+
q.offer(z);
153160
}
154161
}
155162
}
156-
++ans;
157163
}
158164
return -1;
159165
}
160-
161-
private int[] get(int x) {
162-
int i = (x - 1) / n, j = (x - 1) % n;
163-
if (i % 2 == 1) {
164-
j = n - 1 - j;
165-
}
166-
return new int[] {n - 1 - i, j};
167-
}
168166
}
169167
```
170168

@@ -173,40 +171,36 @@ class Solution {
173171
```cpp
174172
class Solution {
175173
public:
176-
int n;
177-
178174
int snakesAndLadders(vector<vector<int>>& board) {
179-
n = board.size();
175+
int n = board.size();
180176
queue<int> q{{1}};
181-
vector<bool> vis(n * n + 1);
177+
int m = n * n;
178+
vector<bool> vis(m + 1);
182179
vis[1] = true;
183-
int ans = 0;
184-
while (!q.empty()) {
185-
for (int t = q.size(); t; --t) {
186-
int curr = q.front();
187-
if (curr == n * n) return ans;
180+
181+
for (int ans = 0; !q.empty(); ++ans) {
182+
for (int k = q.size(); k > 0; --k) {
183+
int x = q.front();
188184
q.pop();
189-
for (int k = curr + 1; k <= min(curr + 6, n * n); ++k) {
190-
auto p = get(k);
191-
int next = k;
192-
int i = p[0], j = p[1];
193-
if (board[i][j] != -1) next = board[i][j];
194-
if (!vis[next]) {
195-
vis[next] = true;
196-
q.push(next);
185+
if (x == m) {
186+
return ans;
187+
}
188+
for (int y = x + 1; y <= min(x + 6, m); ++y) {
189+
int i = (y - 1) / n, j = (y - 1) % n;
190+
if (i % 2 == 1) {
191+
j = n - j - 1;
192+
}
193+
i = n - i - 1;
194+
int z = board[i][j] == -1 ? y : board[i][j];
195+
if (!vis[z]) {
196+
vis[z] = true;
197+
q.push(z);
197198
}
198199
}
199200
}
200-
++ans;
201201
}
202202
return -1;
203203
}
204-
205-
vector<int> get(int x) {
206-
int i = (x - 1) / n, j = (x - 1) % n;
207-
if (i % 2 == 1) j = n - 1 - j;
208-
return {n - 1 - i, j};
209-
}
210204
};
211205
```
212206

@@ -215,43 +209,78 @@ public:
215209
```go
216210
func snakesAndLadders(board [][]int) int {
217211
n := len(board)
218-
get := func(x int) []int {
219-
i, j := (x-1)/n, (x-1)%n
220-
if i%2 == 1 {
221-
j = n - 1 - j
222-
}
223-
return []int{n - 1 - i, j}
224-
}
225212
q := []int{1}
226-
vis := make([]bool, n*n+1)
213+
m := n * n
214+
vis := make([]bool, m+1)
227215
vis[1] = true
228-
ans := 0
229-
for len(q) > 0 {
230-
for t := len(q); t > 0; t-- {
231-
curr := q[0]
232-
if curr == n*n {
216+
217+
for ans := 0; len(q) > 0; ans++ {
218+
for k := len(q); k > 0; k-- {
219+
x := q[0]
220+
q = q[1:]
221+
if x == m {
233222
return ans
234223
}
235-
q = q[1:]
236-
for k := curr + 1; k <= curr+6 && k <= n*n; k++ {
237-
p := get(k)
238-
next := k
239-
i, j := p[0], p[1]
224+
for y := x + 1; y <= min(x+6, m); y++ {
225+
i, j := (y-1)/n, (y-1)%n
226+
if i%2 == 1 {
227+
j = n - j - 1
228+
}
229+
i = n - i - 1
230+
z := y
240231
if board[i][j] != -1 {
241-
next = board[i][j]
232+
z = board[i][j]
242233
}
243-
if !vis[next] {
244-
vis[next] = true
245-
q = append(q, next)
234+
if !vis[z] {
235+
vis[z] = true
236+
q = append(q, z)
246237
}
247238
}
248239
}
249-
ans++
250240
}
251241
return -1
252242
}
253243
```
254244

245+
#### TypeScript
246+
247+
```ts
248+
function snakesAndLadders(board: number[][]): number {
249+
const n = board.length;
250+
const q: number[] = [1];
251+
const m = n * n;
252+
const vis: boolean[] = Array(m + 1).fill(false);
253+
vis[1] = true;
254+
255+
for (let ans = 0; q.length > 0; ans++) {
256+
const nq: number[] = [];
257+
for (const x of q) {
258+
if (x === m) {
259+
return ans;
260+
}
261+
for (let y = x + 1; y <= Math.min(x + 6, m); y++) {
262+
let i = Math.floor((y - 1) / n);
263+
let j = (y - 1) % n;
264+
if (i % 2 === 1) {
265+
j = n - j - 1;
266+
}
267+
i = n - i - 1;
268+
const z = board[i][j] === -1 ? y : board[i][j];
269+
if (!vis[z]) {
270+
vis[z] = true;
271+
nq.push(z);
272+
}
273+
}
274+
}
275+
q.length = 0;
276+
for (const x of nq) {
277+
q.push(x);
278+
}
279+
}
280+
return -1;
281+
}
282+
```
283+
255284
<!-- tabs:end -->
256285

257286
<!-- solution:end -->

0 commit comments

Comments
 (0)