Check if There is a Valid Path in a Grid - Complete Solution Guide
Check if There is a Valid Path in a Grid is LeetCode problem 1391, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
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
Detailed Explanation
The problem asks us to determine if there exists a valid path from the top-left cell (0, 0) to the bottom-right cell (m-1, n-1) in a given m x n grid. Each cell in the grid represents a street with a specific direction (1-6). We can only move along the streets; we cannot change the direction of any street. A valid path is one that starts at (0, 0) and ends at (m-1, n-1) while following the allowed street directions.
Solution Approach
The provided solution uses a Breadth-First Search (BFS) approach to explore the grid. It maintains a queue of cells to visit and a set to keep track of visited cells. Starting from (0, 0), the algorithm explores valid neighbor cells based on the street type of the current cell. A cell is considered a valid neighbor if it's within the grid boundaries, hasn't been visited, and if its street type is compatible with the move from the current cell.
Step-by-Step Algorithm
- Step 1: Initialize a queue with the starting cell (0, 0) and a set to track visited cells, adding (0, 0) to the visited set.
- Step 2: Define a mapping (dictionary/hashmap) of street types to possible moves (directions as (row, col) offsets).
- Step 3: While the queue is not empty, dequeue a cell (r, c).
- Step 4: If the dequeued cell is the destination (m-1, n-1), return true (a valid path exists).
- Step 5: Get the street type of the current cell.
- Step 6: Iterate through the possible moves for the current street type.
- Step 7: For each move (dr, dc), calculate the neighbor's coordinates (nr, nc).
- Step 8: Check if the neighbor is within the grid boundaries (0 <= nr < m and 0 <= nc < n).
- Step 9: Check if the neighbor has not been visited.
- Step 10: Check if the neighbor's street type is compatible with the move from the current cell. This is done by checking if the opposite move (-dr, -dc) is a valid move for the neighbor's street type.
- Step 11: If all the above conditions are met, mark the neighbor as visited and enqueue it.
- Step 12: If the queue becomes empty and the destination has not been reached, return false (no valid path exists).
Key Insights
- Insight 1: Representing the street connections as possible moves from a cell allows for traversal using graph traversal algorithms.
- Insight 2: A Breadth-First Search (BFS) or Depth-First Search (DFS) algorithm can be used to explore the grid.
- Insight 3: A critical check is to ensure that the neighbor street is compatible with the move we just made. For example, if we move right from cell A to cell B, cell B must allow a connection coming from the left.
Complexity Analysis
Time Complexity: O(m*n)
Space Complexity: O(m*n)
Topics
This problem involves: Array, Depth-First Search, Breadth-First Search, Union Find, Matrix.
Companies
Asked at: Robinhood.