Snakes And Ladders Leetcode Problem 909 [Python Solution]
Snakes And Ladders Leetcode problem, which is categorized under medium difficulty and falls in the Graphs category is a great opportunity to explore.
An interesting algorithmic challenge that requires a well-thought-out approach.
We’ll provide a Python solution and dive into its code and reasoning.
Problem: You are given an n x n integer matrix board where the cells are labeled from 1 to n^2 in a Boustrophedon style starting from the bottom left of the board.
You start on square 1 of the board.
In each move, starting from square curr, you choose a destination square next with a label in the range [curr + 1, min(curr + 6, n^2)].
If the square “next” has a snake or ladder, you must move to the destination of that snake or ladder.
Otherwise, you move to square “next.” The game ends when you reach square n^2. A board square on row r and column c has a snake or ladder if board[r][c] != -1. Squares 1 and n^2 do not have a snake or ladder.
The goal is to return the least number of moves required to reach the square n^2. If it is not possible to reach the square, return -1.
Example 1:
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]]
Output: 4
Explanation:
In the beginning, you start at square 1 (at row 5, column 0).
You decide to move to square 2 and must take the ladder to square 15. You then decide to move to square 17 and must take the snake to square 13. You then decide to move to square 14 and must take the ladder to square 35. You then decide to move to square 36, ending the game.
This is the lowest possible number of moves to reach the last square, so return 4.
Example 2:
Input: board = [[-1,-1],[-1,3]]
Output: 1
Constraints:
– n == board.length == board[i].length
– 2 <= n <= 20
– board[i][j] is either -1 or in the range [1, n^2]
.
– The squares labeled 1 and n^2 do not have any ladders or snakes.
Before we jump into the code, let’s break down the problem and discuss the approach we will take.
Problem Overview
The problem can be summarized as follows: Given a game board with snakes and ladders, we want to find the minimum number of moves required to reach the end of the board, starting from position 1.
If it’s not possible to reach the end, we return -1. To solve this problem efficiently, we’ll use a breadth-first search (BFS) algorithm.
The BFS algorithm is well-suited for finding the shortest path in a graph, making it a natural choice for this problem.
Example 1:
Let’s illustrate the process with the provided example:
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]]
- We start at square 1, which is at row 5, column 0.
- We roll a die (6-sided) and explore up to 6 possible moves.
- For each move, we check if the destination square has a snake or ladder.
If it does, we move to the destination of the snake or ladder; otherwise, we move to the next square.
4. We continue this process until we reach square 36 (n^2), which is the end of the game.
In this example, the minimum number of moves required to reach square 36 is 4. Now, let’s discuss the details of the approach.
Understanding Snakes and Ladders Constraints
Before we dive into the code, it’s important to understand the constraints and some key concepts related to the problem:
- n: The size of the game board is n x n.
- Snakes and Ladders: Certain squares on the board have snakes or ladders, represented by non-negative values in the board matrix.
These special squares provide shortcuts or detours in the game.
Game Rules:
- You can move from square curr to the next square next with a label in the range [curr + 1, min(curr + 6, n^2)].
- The game ends when you reach square n^2.
- You can only use a snake or ladder once per move.
If you land on a square with a snake or ladder, you must move to its destination.
You cannot use another snake or ladder immediately.
Keeping these constraints in mind, we can proceed with the solution.
Snakes And Ladders LeetCode Problem Solution
We’ll start with the Python solution that uses the BFS algorithm.
This solution efficiently explores the game board to find the minimum number of moves required to reach the end.
Here’s the code:
class Solution:
def snakesAndLadders(self, board: List[List[int]]) -> int:
length = len(board)
board.reverse() # Reverse the board to simplify indexing
# Helper function to convert square number to row, column coordinates
def intToPos(square):
r = (square - 1) // length
c = (square - 1) % length
if r % 2:
c = length - 1 - c
return [r, c]
# Initialize a queue for BFS
q = deque()
q.append([1, 0]) # [square, moves]
visit = set() # Keep track of visited squares
while q:
square, moves = q.popleft()
for i in range(1, 7):
nextSquare = square + i
r, c = intToPos(nextSquare)
# Check if there's a snake or ladder at this square
if board[r][c] != -1:
nextSquare = board[r][c]
# If we reach the last square, return the number of moves
if nextSquare == length * length:
return moves + 1
# If we haven't visited this square before, add it to the queue
if nextSquare not in visit:
visit.add(nextSquare)
q.append([nextSquare, moves + 1])
return -1 # If we can't reach the end
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]]
solution = Solution()
print(solution.snakesAndLadders(board)) # Output: 4
Let’s break down the code:
- We define the
Solution
class with a methodsnakesAndLadders
that takes theboard
as input. - We get the length of the game board, which is the number of rows (or columns) in the square matrix.
- To simplify indexing, we reverse the board.
This makes it easier to map square numbers to row and column coordinates.
- We define a helper function,
intToPos
, to convert a square number to row and column coordinates based on the game board’s layout.
We take advantage of the Boustrophedon style of labeling squares to calculate the position.
- We initialize a queue
q
for the BFS algorithm and append the starting square (square 1) with 0 moves to the queue.
The moves variable keeps track of the number of moves taken to reach the current square.
- We also initialize a
visit
set to keep track of visited squares to prevent revisiting them. - The main BFS loop begins.
We pop squares from the queue and explore up to 6 possible moves (rolling a 6-sided die).
- For each move, we calculate the coordinates of the next square using the
intToPos
function.
If there’s a snake or ladder at the square, we update the nextSquare
accordingly.
- We check if we have reached the last square,
length * length
, which indicates the end of the game.
If we have, we return the total number of moves it took to reach the end.
- If we haven’t reached the end, and we haven’t visited the
nextSquare
before, we add it to the queue and mark it as visited.
We also increment the number of moves taken to reach this square.
- If the BFS loop completes without reaching the end, we return -1 to indicate that it’s not possible to reach the end.
- In the example usage, we create an instance of the
Solution
class, pass the exampleboard
, and print the result.
This solution efficiently explores the game board using BFS to find the minimum number of moves required to reach the end.
It considers the presence of snakes and ladders, updates the position accordingly, and ensures that each square is visited only once.
Let’s check the result for the provided examples:
- Example 1:
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]]
Output: 4
Explanation:
Starting at square 1, the path is 1 → 2 (ladder to 15) → 17 (snake to 13) → 14 (ladder to 35) → 36 (end).
The minimum number of moves is 4.
- Example 2:
Input:board = [[-1,-1],[-1,3]]
Output: 1
Explanation:
Starting at square 1, the path is 1 → 2. The minimum number of moves is 1. The code produces the expected results for these examples.
Complexity Analysis
Let’s analyze the time and space complexity of this solution:
- Time Complexity: The time complexity is determined by the BFS traversal of the game board.
In the worst case, where all squares are visited, the time complexity is O(n^2)
because there are n^2 squares to explore.
Additionally, for each square, we may perform a constant amount of work to explore up to 6 possible moves.
Therefore, the overall time complexity is O(n^2)
.
- Space Complexity: The space complexity is determined by the queue and the
visit
set.
The space required to store the queue is O(n^2)
, and the space required for the visit
set is also O(n^2)
in the worst case.
Therefore, the overall space complexity is O(n^2)
.
This solution efficiently handles the problem within the given constraints and provides the minimum number of moves required to reach the end of the game.
Related Interview Questions By Company:
- Ones And Zeroes LeetCode
- Maximum Product Of The Length Of Two Palindromic Subsequences
- Encode And Decode Tinyurl LeetCode
Related Interview Questions By Difficulty:
Related Interview Questions By Category:
Summary
In this blog post, we tackled the Snakes And Ladders problem on LeetCode.
We used a breadth-first search (BFS) algorithm to efficiently explore the game board and find the minimum number of moves required to reach the end of the board.
We also considered the presence of snakes and ladders, updating the position accordingly and marking visited squares to avoid revisiting them.
The code produced the correct results for the provided examples, and we analyzed its time and space complexity.
I hope this solution and explanation were helpful in understanding the problem and solving it effectively.
Happy coding!
Note: The code provided here can be further optimized for space by avoiding reversing the board and using a mapping function to calculate the position, but it is presented here for clarity and simplicity.