|
| 1 | +/* |
| 2 | +
|
| 3 | +
|
| 4 | +
|
| 5 | +-* 909. Snakes and Ladders *- |
| 6 | +
|
| 7 | +
|
| 8 | +
|
| 9 | +You are given an n x n integer matrix board where the cells are labeled from 1 to n2 in a Boustrophedon style starting from the bottom left of the board (i.e. board[n - 1][0]) and alternating direction each row. |
| 10 | +
|
| 11 | +You start on square 1 of the board. In each move, starting from square curr, do the following: |
| 12 | +
|
| 13 | +Choose a destination square next with a label in the range [curr + 1, min(curr + 6, n2)]. |
| 14 | +This choice simulates the result of a standard 6-sided die roll: i.e., there are always at most 6 destinations, regardless of the size of the board. |
| 15 | +If next has a snake or ladder, you must move to the destination of that snake or ladder. Otherwise, you move to next. |
| 16 | +The game ends when you reach the square n2. |
| 17 | +A board square on row r and column c has a snake or ladder if board[r][c] != -1. The destination of that snake or ladder is board[r][c]. Squares 1 and n2 do not have a snake or ladder. |
| 18 | +
|
| 19 | +Note that you only take a snake or ladder at most once per move. If the destination to a snake or ladder is the start of another snake or ladder, you do not follow the subsequent snake or ladder. |
| 20 | +
|
| 21 | +For example, suppose the board is [[-1,4],[-1,3]], and on the first move, your destination square is 2. You follow the ladder to square 3, but do not follow the subsequent ladder to 4. |
| 22 | +Return the least number of moves required to reach the square n2. If it is not possible to reach the square, return -1. |
| 23 | +
|
| 24 | + |
| 25 | +
|
| 26 | +Example 1: |
| 27 | +
|
| 28 | +
|
| 29 | +Input: board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]] |
| 30 | +Output: 4 |
| 31 | +Explanation: |
| 32 | +In the beginning, you start at square 1 (at row 5, column 0). |
| 33 | +You decide to move to square 2 and must take the ladder to square 15. |
| 34 | +You then decide to move to square 17 and must take the snake to square 13. |
| 35 | +You then decide to move to square 14 and must take the ladder to square 35. |
| 36 | +You then decide to move to square 36, ending the game. |
| 37 | +This is the lowest possible number of moves to reach the last square, so return 4. |
| 38 | +Example 2: |
| 39 | +
|
| 40 | +Input: board = [[-1,-1],[-1,3]] |
| 41 | +Output: 1 |
| 42 | + |
| 43 | +
|
| 44 | +Constraints: |
| 45 | +
|
| 46 | +n == board.length == board[i].length |
| 47 | +2 <= n <= 20 |
| 48 | +grid[i][j] is either -1 or in the range [1, n2]. |
| 49 | +The squares labeled 1 and n2 do not have any ladders or snakes. |
| 50 | +
|
| 51 | +*/ |
| 52 | +import 'dart:collection'; |
| 53 | + |
| 54 | +class A { |
| 55 | + int length = 1; |
| 56 | + int snakesAndLadders(List<List<int>> board) { |
| 57 | + length = board.length; |
| 58 | + HashMap<int, int> visited = new HashMap(); |
| 59 | + visited[1] = 0; |
| 60 | + List<int> arr = []; |
| 61 | + arr.add(1); |
| 62 | + while (arr.isNotEmpty) { |
| 63 | + int n = arr[0]; |
| 64 | + arr.remove(0); |
| 65 | + for (int i = n + 1; i <= n + 6; i++) { |
| 66 | + int next = i; |
| 67 | + List<int> nextPos = getPosition(i); |
| 68 | + if (next > length * length) return -1; |
| 69 | + if (board[nextPos[0]][nextPos[1]] != -1) { |
| 70 | + next = board[nextPos[0]][nextPos[1]]; |
| 71 | + } |
| 72 | + if (next == length * length) return (visited[n] ?? 0) + 1; |
| 73 | + if (!visited.containsKey(next)) { |
| 74 | + visited[next] = (visited[n] ?? 0) + 1; |
| 75 | + arr.add(next); |
| 76 | + } |
| 77 | + } |
| 78 | + } |
| 79 | + return -1; |
| 80 | + } |
| 81 | + |
| 82 | + List<int> getPosition(int n) { |
| 83 | + int row = (n - 1) ~/ length; |
| 84 | + int column = (n - 1) % length; |
| 85 | + if (row % 2 != 0) { |
| 86 | + column = (column - length + 1) * -1; |
| 87 | + } |
| 88 | + row = (row - length + 1) * -1; |
| 89 | + |
| 90 | + List<int> result = [row, column]; |
| 91 | + return result; |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +class B { |
| 96 | + int snakesAndLadders(List<List<int>> board) { |
| 97 | + int n = board.length; |
| 98 | + int moves = 0; |
| 99 | + Queue<int> q = Queue(); |
| 100 | + List<List<bool>> visited = |
| 101 | + List.filled(n, false).map((e) => List.filled(n, false)).toList(); |
| 102 | + q.add(1); |
| 103 | + visited[n - 1][0] = true; |
| 104 | + while (q.isNotEmpty) { |
| 105 | + int size = q.length; |
| 106 | + for (int i = 0; i < size; i++) { |
| 107 | + // poll = removeLast() |
| 108 | + int currBoardVal = q.removeFirst(); |
| 109 | + if (currBoardVal == n * n) return moves; |
| 110 | + for (int diceVal = 1; diceVal <= 6; diceVal++) { |
| 111 | + if (currBoardVal + diceVal > n * n) break; |
| 112 | + List<int> pos = findCoordinates(currBoardVal + diceVal, n); |
| 113 | + int row = pos[0]; |
| 114 | + int col = pos[1]; |
| 115 | + if (visited[row][col] == false) { |
| 116 | + visited[row][col] = true; |
| 117 | + if (board[row][col] == -1) { |
| 118 | + q.add(currBoardVal + diceVal); |
| 119 | + } else { |
| 120 | + q.add(board[row][col]); |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + moves++; |
| 126 | + } |
| 127 | + return -1; |
| 128 | + } |
| 129 | + |
| 130 | + List<int> findCoordinates(int curr, int n) { |
| 131 | + int r = n - (curr - 1) ~/ n - 1; |
| 132 | + int c = (curr - 1) % n; |
| 133 | + if (r % 2 == n % 2) { |
| 134 | + return [r, n - 1 - c]; |
| 135 | + } else { |
| 136 | + return [r, c]; |
| 137 | + } |
| 138 | + } |
| 139 | +} |
0 commit comments