Solving Leetcode Interviews in Seconds with AI: Check if There is a Valid Path in a Grid
Introduction
In this blog post, we will explore how to solve the LeetCode problem "1391" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
You are given an m x n grid. Each cell of grid represents a street. The street of grid[i][j] can be: 1 which means a street connecting the left cell and the right cell. 2 which means a street connecting the upper cell and the lower cell. 3 which means a street connecting the left cell and the lower cell. 4 which means a street connecting the right cell and the lower cell. 5 which means a street connecting the left cell and the upper cell. 6 which means a street connecting the right cell and the upper cell. You will initially start at the street of the upper-left cell (0, 0). A valid path in the grid is a path that starts from the upper left cell (0, 0) and ends at the bottom-right cell (m - 1, n - 1). The path should only follow the streets. Notice that you are not allowed to change any street. Return true if there is a valid path in the grid or false otherwise. Example 1: Input: grid = [[2,4,3],[6,5,2]] Output: true Explanation: As shown you can start at cell (0, 0) and visit all the cells of the grid to reach (m - 1, n - 1). Example 2: Input: grid = [[1,2,1],[1,2,1]] Output: false Explanation: As shown you the street at cell (0, 0) is not connected with any street of any other cell and you will get stuck at cell (0, 0) Example 3: Input: grid = [[1,1,2]] Output: false Explanation: You will get stuck at cell (0, 1) and you cannot reach cell (0, 2). Constraints: m == grid.length n == grid[i].length 1 <= m, n <= 300 1 <= grid[i][j] <= 6
Explanation
Here's the solution:
- Approach: Use Depth-First Search (DFS) to explore the grid. Start at (0, 0) and recursively check adjacent cells based on the street type at the current cell. Mark visited cells to avoid cycles.
- Complexity:
- Runtime: O(m * n) - where m is the number of rows and n is the number of columns in the grid. We visit each cell at most once.
- Storage: O(m n) - in the worst case, the recursion depth can be proportional to the number of cells in the grid. Also, we use O(mn) space to store the visited array.
Code
def hasValidPath(grid):
m, n = len(grid), len(grid[0])
visited = [[False] * n for _ in range(m)]
def isValid(r, c):
return 0 <= r < m and 0 <= c < n and not visited[r][c]
def dfs(r, c):
if r == m - 1 and c == n - 1:
return True
visited[r][c] = True
street = grid[r][c]
# Possible movements based on street type
if street == 1:
possible_moves = [(r, c - 1), (r, c + 1)]
elif street == 2:
possible_moves = [(r - 1, c), (r + 1, c)]
elif street == 3:
possible_moves = [(r, c - 1), (r + 1, c)]
elif street == 4:
possible_moves = [(r, c + 1), (r + 1, c)]
elif street == 5:
possible_moves = [(r, c - 1), (r - 1, c)]
else: # street == 6
possible_moves = [(r, c + 1), (r - 1, c)]
for nr, nc in possible_moves:
if isValid(nr, nc):
next_street = grid[nr][nc]
# Check if the current street connects to the next street
if street == 1:
if (next_street == 1 and (nr, nc) == (r, c - 1)) or \
(next_street in [1, 4, 6] and (nr, nc) == (r, c + 1)):
if dfs(nr, nc):
return True
elif street == 2:
if (next_street == 2 and (nr, nc) == (r - 1, c)) or \
(next_street in [2, 3, 4] and (nr, nc) == (r + 1, c)):
if dfs(nr, nc):
return True
elif street == 3:
if (next_street in [1, 4, 6] and (nr, nc) == (r, c - 1)) or \
(next_street in [2, 3, 4] and (nr, nc) == (r + 1, c)):
if dfs(nr, nc):
return True
elif street == 4:
if (next_street in [1, 3, 5] and (nr, nc) == (r, c + 1)) or \
(next_street in [2, 3, 4] and (nr, nc) == (r + 1, c)):
if dfs(nr, nc):
return True
elif street == 5:
if (next_street in [1, 4, 6] and (nr, nc) == (r, c - 1)) or \
(next_street == 2 and (nr, nc) == (r - 1, c)) :
if dfs(nr, nc):
return True
elif street == 6:
if (next_street in [1, 3, 5] and (nr, nc) == (r, c + 1)) or \
(next_street == 2 and (nr, nc) == (r - 1, c)):
if dfs(nr, nc):
return True
return False
return dfs(0, 0)