leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit 6ae28ab4a88ede5b536e3f6625a08c249af4d562
parent e1a3b8039965502c833f0bac3e8b3ef92b5cff23
Author: Jack Sangdahl <jack@pngu.org>
Date:   Sun, 26 Apr 2026 21:18:18 -0600

1391. check if there is a valid path in a grid

Diffstat:
Acheck_valid_path_grid.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acheck_valid_path_grid.py | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/check_valid_path_grid.c b/check_valid_path_grid.c @@ -0,0 +1,99 @@ +// 1391. Check if There is a Valid Path in a Grid +#include "leetcode.h" + +/* + * you are given an 'm x n' 'grid'. each cell of 'grid' represents a street. the + * street of 'grid[i][j]' can be 1 .. 6, connecting to a left/upper/right cell + * and the right/lower/upper cell. you will initially start at the street of the + * upper left cell '(0, 0)'. a valid path in the grid is the 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. + */ + +bool has_opening(int type, int dir) { + if (type == 1) + return dir == 0 || dir == 1; + if (type == 2) + return dir == 2 || dir == 3; + if (type == 3) + return dir == 0 || dir == 3; + if (type == 4) + return dir == 1 || dir == 3; + if (type == 5) + return dir == 0 || dir == 2; + if (type == 6) + return dir == 1 || dir == 2; + return false; +} + +bool hasValidPath(int **grid, int gridSize, int *gridColSize) { + int m = gridSize, n = gridColSize[0]; + if (m == 1 && n == 1) + return true; + static int dirs[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; + static int next_step[7][4] = {{4, 4, 4, 4}, {1, 0, 4, 4}, {4, 4, 3, 2}, + {3, 4, 4, 0}, {4, 3, 4, 1}, {2, 4, 0, 4}, + {4, 2, 1, 4}}; + int start_type = grid[0][0]; + bool **vis = (bool **)calloc(m, sizeof(bool *)); + for (int i = 0; i < m; i++) + vis[i] = (bool *)calloc(n, sizeof(bool)); + for (int d = 0; d < 4; d++) { + if (!has_opening(start_type, d)) + continue; + int r = 0, c = 0, out_dir = d; + vis[0][0] = true; + while (true) { + int nr = r + dirs[out_dir][0]; + int nc = c + dirs[out_dir][1]; + if (nr < 0 || nr >= m || nc < 0 || nc >= n || vis[nr][nc]) + break; + int in_dir = !(out_dir % 2) ? out_dir + 1 : out_dir - 1; + int n_type = grid[nr][nc]; + if (!has_opening(n_type, in_dir)) + break; + if (nr == m - 1 && nc == n - 1) { + for (int i = 0; i < m; i++) + free(vis[i]); + free(vis); + return true; + } + vis[nr][nc] = true; + r = nr; + c = nc; + out_dir = next_step[n_type][in_dir]; + if (out_dir == 4) + break; + } + } + for (int i = 0; i < m; i++) + free(vis[i]); + free(vis); + return false; +} + +int main() { + int g1i[2][3] = {{2, 4, 3}, {6, 5, 2}}; + int g2i[2][3] = {{1, 2, 1}, {1, 2, 1}}; + int g3i[1][3] = {{1, 1, 2}}; + struct two_d_arr *g1 = + two_d_arr_init(ARRAY_SIZE(g1i), ARRAY_SIZE(g1i[0]), g1i); + struct two_d_arr *g2 = + two_d_arr_init(ARRAY_SIZE(g2i), ARRAY_SIZE(g2i[0]), g2i); + struct two_d_arr *g3 = + two_d_arr_init(ARRAY_SIZE(g3i), ARRAY_SIZE(g3i[0]), g3i); + bool r1 = hasValidPath(g1->arr, g1->row_size, g1->col_size); + bool r2 = hasValidPath(g2->arr, g2->row_size, g2->col_size); + bool r3 = hasValidPath(g3->arr, g3->row_size, g3->col_size); + printf("%d\n", r1); + assert(r1 == true); + printf("%d\n", r2); + assert(r2 == false); + printf("%d\n", r3); + assert(r3 == false); + two_d_arr_free(g1); + two_d_arr_free(g2); + two_d_arr_free(g3); +} diff --git a/check_valid_path_grid.py b/check_valid_path_grid.py @@ -0,0 +1,54 @@ +# 1391. Check if There is a Valid Path in a Grid +from typing import List + +""" +you are given an 'm x n' 'grid'. each cell of 'grid' represents a street. the +street of 'grid[i][j]' can be 1 .. 6, connecting to a left/upper/right cell +and the right/lower/upper cell. you will initially start at the street of the +upper left cell '(0, 0)'. a valid path in the grid is the 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. +""" + + +class Solution: + def hasValidPath(self, grid: List[List[int]]) -> bool: + if not grid: + return true + directions = { + 1: [(0, -1), (0, 1)], + 2: [(-1, 0), (1, 0)], + 3: [(0, -1), (1, 0)], + 4: [(0, 1), (1, 0)], + 5: [(0, -1), (-1, 0)], + 6: [(0, 1), (-1, 0)], + } + vis = set() + goal = (len(grid) - 1, len(grid[0]) - 1) + + def dfs(i, j): + vis.add((i, j)) + if (i, j) == goal: + return True + for d in directions[grid[i][j]]: + ni, nj = i + d[0], j + d[1] + if ( + 0 <= ni < len(grid) + and 0 <= nj < len(grid[0]) + and (ni, nj) not in vis + and (-d[0], -d[1]) in directions[grid[ni][nj]] + ): + if dfs(ni, nj): + return True + return False + + return dfs(0, 0) + + +if __name__ == "__main__": + obj = Solution() + print(obj.hasValidPath(grid=[[2, 4, 3], [6, 5, 2]])) + print(obj.hasValidPath(grid=[[1, 2, 1], [1, 2, 1]])) + print(obj.hasValidPath(grid=[[1, 1, 2]]))