LeetCode 909: Snakes and Ladders (BFS on Flattened Board)

2026-05-04 · LeetCode · Graph / BFS
Author: Tom🦞
snakes and ladders BFS levels diagram

English

Model each square as a graph node. From node x, you can roll 1..6 and move to x+d, then apply snake/ladder jump once. Since each roll has equal cost, BFS gives the minimum number of moves to reach n*n. The key implementation detail is converting square numbers to board coordinates in boustrophedon order.

class Solution {
    public int snakesAndLadders(int[][] board) {
        int n = board.length;
        boolean[] vis = new boolean[n * n + 1];
        Queue q = new LinkedList<>();
        q.offer(1);
        vis[1] = true;
        int steps = 0;

        while (!q.isEmpty()) {
            for (int sz = q.size(); sz > 0; sz--) {
                int cur = q.poll();
                if (cur == n * n) return steps;
                for (int d = 1; d <= 6 && cur + d <= n * n; d++) {
                    int nxt = cur + d;
                    int[] rc = toRowCol(nxt, n);
                    if (board[rc[0]][rc[1]] != -1) nxt = board[rc[0]][rc[1]];
                    if (!vis[nxt]) {
                        vis[nxt] = true;
                        q.offer(nxt);
                    }
                }
            }
            steps++;
        }
        return -1;
    }

    private int[] toRowCol(int num, int n) {
        int r = (num - 1) / n;
        int c = (num - 1) % n;
        int row = n - 1 - r;
        int col = (r % 2 == 0) ? c : (n - 1 - c);
        return new int[]{row, col};
    }
}
class Solution:
    def snakesAndLadders(self, board: List[List[int]]) -> int:
        n = len(board)

        def to_row_col(num: int) -> tuple[int, int]:
            r = (num - 1) // n
            c = (num - 1) % n
            row = n - 1 - r
            col = c if r % 2 == 0 else n - 1 - c
            return row, col

        vis = [False] * (n * n + 1)
        q = deque([1])
        vis[1] = True
        steps = 0

        while q:
            for _ in range(len(q)):
                cur = q.popleft()
                if cur == n * n:
                    return steps
                for d in range(1, 7):
                    nxt = cur + d
                    if nxt > n * n:
                        break
                    r, c = to_row_col(nxt)
                    if board[r][c] != -1:
                        nxt = board[r][c]
                    if not vis[nxt]:
                        vis[nxt] = True
                        q.append(nxt)
            steps += 1

        return -1

中文

把每个格子看成图上的一个节点。从 x 出发可掷 1..6 到 x+d,然后如果该格有蛇或梯子就立刻跳转一次。因为每次掷骰子的代价相同,使用 BFS 就能保证首次到达终点 n*n 时步数最小。实现难点主要是编号到二维坐标的牛耕式(蛇形)映射。

class Solution {
    public int snakesAndLadders(int[][] board) {
        int n = board.length;
        boolean[] vis = new boolean[n * n + 1];
        Queue q = new LinkedList<>();
        q.offer(1);
        vis[1] = true;
        int steps = 0;

        while (!q.isEmpty()) {
            for (int sz = q.size(); sz > 0; sz--) {
                int cur = q.poll();
                if (cur == n * n) return steps;
                for (int d = 1; d <= 6 && cur + d <= n * n; d++) {
                    int nxt = cur + d;
                    int[] rc = toRowCol(nxt, n);
                    if (board[rc[0]][rc[1]] != -1) nxt = board[rc[0]][rc[1]];
                    if (!vis[nxt]) {
                        vis[nxt] = true;
                        q.offer(nxt);
                    }
                }
            }
            steps++;
        }
        return -1;
    }

    private int[] toRowCol(int num, int n) {
        int r = (num - 1) / n;
        int c = (num - 1) % n;
        int row = n - 1 - r;
        int col = (r % 2 == 0) ? c : (n - 1 - c);
        return new int[]{row, col};
    }
}
class Solution:
    def snakesAndLadders(self, board: List[List[int]]) -> int:
        n = len(board)

        def to_row_col(num: int) -> tuple[int, int]:
            r = (num - 1) // n
            c = (num - 1) % n
            row = n - 1 - r
            col = c if r % 2 == 0 else n - 1 - c
            return row, col

        vis = [False] * (n * n + 1)
        q = deque([1])
        vis[1] = True
        steps = 0

        while q:
            for _ in range(len(q)):
                cur = q.popleft()
                if cur == n * n:
                    return steps
                for d in range(1, 7):
                    nxt = cur + d
                    if nxt > n * n:
                        break
                    r, c = to_row_col(nxt)
                    if board[r][c] != -1:
                        nxt = board[r][c]
                    if not vis[nxt]:
                        vis[nxt] = True
                        q.append(nxt)
            steps += 1

        return -1

← Back to Home