DDSA Solutions

1391. Check if There is a Valid Path in a Grid

Time: O(m*n)
Space: O(m*n)
Advertisement

Intuition

Instead of manually validating every street-type pair at cell boundaries, expand each original cell into a 3x3 pixel block where valid street segments are drawn as connected true cells. Then the problem becomes a plain connectivity query: is there any continuous path from the expanded start center to expanded end center?

Algorithm

  1. 1Create a boolean grid of size (m*3) x (n*3).
  2. 2For each street type (1..6), mark the corresponding three pixels in that 3x3 block to represent its road shape.
  3. 3Start DFS from expanded coordinate (1,1), which is the center of top-left cell.
  4. 4During DFS, stop when out of bounds or on a false cell; otherwise mark current pixel visited and move in 4 directions.
  5. 5If DFS reaches (m*3-2, n*3-2), which is center of bottom-right cell, return true.
  6. 6If traversal ends without reaching destination, return false.

Example Walkthrough

Input: grid = [[2,4,3],[6,5,2]]

  1. 1.Build expanded map where each street draws its passable pixels.
  2. 2.From start center, DFS follows only connected road pixels.
  3. 3.Because neighboring street segments match, traversal can continue through the route.
  4. 4.Destination center is reached, so a valid path exists.

Output: true

Common Pitfalls

  • Street encoding must be exact for each type; a wrong pixel pattern causes false positives/negatives.
  • Always mark visited during DFS to prevent infinite recursion loops.
  • This recursion can be deep on large grids; iterative DFS/BFS is an alternative if stack depth is a concern.
1391.cs
C#
public class Solution
{
    // Approach: Expand each cell to a 3x3 mini-grid that encodes street connectivity,
    // then DFS from start to destination on expanded walkable pixels.
    // Time: O(m*n) Space: O(m*n)
    public bool HasValidPath(int[][] grid)
    {
        int m = grid.Length;
        int n = grid[0].Length;
        bool[,] g = new bool[m * 3, n * 3];

        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                switch (grid[i][j])
                {
                    case 1:
                        g[i * 3 + 1, j * 3 + 0] = true;
                        g[i * 3 + 1, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 2] = true;
                        break;
                    case 2:
                        g[i * 3 + 0, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 1] = true;
                        g[i * 3 + 2, j * 3 + 1] = true;
                        break;
                    case 3:
                        g[i * 3 + 1, j * 3 + 0] = true;
                        g[i * 3 + 1, j * 3 + 1] = true;
                        g[i * 3 + 2, j * 3 + 1] = true;
                        break;
                    case 4:
                        g[i * 3 + 1, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 2] = true;
                        g[i * 3 + 2, j * 3 + 1] = true;
                        break;
                    case 5:
                        g[i * 3 + 0, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 0] = true;
                        g[i * 3 + 1, j * 3 + 1] = true;
                        break;
                    case 6:
                        g[i * 3 + 0, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 1] = true;
                        g[i * 3 + 1, j * 3 + 2] = true;
                        break;
                }
            }
        }

        return Dfs(g, 1, 1);
    }

    private bool Dfs(bool[,] g, int i, int j)
    {
        if (i < 0 || i == g.GetLength(0) || j < 0 || j == g.GetLength(1))
            return false;
        if (!g[i, j]) // There's no path here.
            return false;
        if (i == g.GetLength(0) - 2 && j == g.GetLength(1) - 2)
            return true;

        g[i, j] = false; // Mark as visited.
        return Dfs(g, i + 1, j) || Dfs(g, i - 1, j) || Dfs(g, i, j + 1) || Dfs(g, i, j - 1);
    }
}
Advertisement
Was this solution helpful?