leetcode

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

commit bf1a8409bf56b56a8d44ddfe5934a39e9d9ef339
parent b3e8f9306953f5cb89c50fd9ee4b344f68fc2388
Author: Jack Sangdahl <jack@pngu.org>
Date:   Thu,  2 Jul 2026 22:01:40 -0600

3286. find a safe walk through a grid

Diffstat:
Afind_safe_walk_through_grid.c | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afind_safe_walk_through_grid.py | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 159 insertions(+), 0 deletions(-)

diff --git a/find_safe_walk_through_grid.c b/find_safe_walk_through_grid.c @@ -0,0 +1,101 @@ +// 3286. Find a Safe Walk Through a Grid +#include "leetcode.h" + +/* + * you are given an 'm x n' binary matrix 'grid' and an integer 'health'. you + * start on the upper left corner and would like to get to the lower right + * corner. you can move up, down, left, or right from one cell to another + * adjacent cell as long as your health remains positive. cells '(i, j)' with + * grid 'grid[i][j] == 1' are considered unsafe and reduce your health by 1. + * return true if you can reach the final cell with a health of value 1 or more, + * and false otherwise. + */ + +struct pair { + int x; + int y; +}; + +bool findSafeWalk(int **grid, int gridSize, int *gridColSize, int health) { + int row = gridSize, col = gridColSize[0]; + int **dist = (int **)malloc(row * sizeof(int *)); + for (int i = 0; i < row; i++) { + dist[i] = (int *)malloc(col * sizeof(int)); + for (int j = 0; j < col; j++) + dist[i][j] = -2; + } + int max_size = row * col * 2 + 5; + struct pair *q = (struct pair *)malloc(max_size * sizeof(struct pair)); + int front = max_size / 2, back = max_size / 2; + q[back++] = (struct pair){0, 0}; + if (grid[0][0]) { + dist[0][0] = health - 1; + if (dist[0][0] <= 0) { + for (int i = 0; i < row; i++) + free(dist[i]); + free(dist); + free(q); + return false; + } + } else + dist[0][0] = health; + int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + while (front < back) { + struct pair curr = q[front++]; + int i = curr.x, j = curr.y; + if (i == row - 1 && j == col - 1) { + for (int k = 0; k < row; k++) + free(dist[k]); + free(dist); + free(q); + return true; + } + for (int d = 0; d < 4; d++) { + int x = i + dirs[d][0]; + int y = j + dirs[d][1]; + if (x >= 0 && x < row && y >= 0 && y < col && dist[x][y] == -2) { + int cost = grid[x][y] == 1 ? 1 : 0; + int new_health = dist[i][j] - cost; + if (new_health > 0 && new_health > dist[x][y]) { + dist[x][y] = new_health; + if (!cost) + q[--front] = (struct pair){x, y}; + else + q[back++] = (struct pair){x, y}; + } + } + } + } + for (int i = 0; i < row; i++) + free(dist[i]); + free(dist); + free(q); + return false; +} + +int main() { + int g1i[3][5] = {{0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 1, 0}}; + int g2i[4][6] = {{0, 1, 1, 0, 0, 0}, + {1, 0, 1, 0, 0, 0}, + {0, 1, 1, 1, 0, 1}, + {0, 0, 1, 0, 1, 0}}; + int g3i[3][3] = {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}; + 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 = findSafeWalk(g1->arr, g1->row_size, g1->col_size, 1); + bool r2 = findSafeWalk(g2->arr, g2->row_size, g2->col_size, 3); + bool r3 = findSafeWalk(g3->arr, g3->row_size, g3->col_size, 5); + printf("%d\n", r1); + assert(r1 == true); + printf("%d\n", r2); + assert(r2 == false); + printf("%d\n", r3); + assert(r3 == true); + two_d_arr_free(g1); + two_d_arr_free(g2); + two_d_arr_free(g3); +} diff --git a/find_safe_walk_through_grid.py b/find_safe_walk_through_grid.py @@ -0,0 +1,58 @@ +# 3286. Find a Safe Walk Through a Grid +from functools import lru_cache +from itertools import product + +""" +you are given an 'm x n' binary matrix 'grid' and an integer 'health'. you +start on the upper left corner and would like to get to the lower right +corner. you can move up, down, left, or right from one cell to another +adjacent cell as long as your health remains positive. cells '(i, j)' with +grid 'grid[i][j] == 1' are considered unsafe and reduce your health by 1. +return true if you can reach the final cell with a health of value 1 or more, +and false otherwise. +""" + + +class Solution: + def findSafeWalk(self, grid: List[List[int]], health: int) -> bool: + @lru_cache(None) + def dp(x, y, health_used): + if health_used == health or (x, y) not in eligible: + return float("inf") + cnt = health_used + grid[x][y] + if (x, y) == (m - 1, n - 1): + return cnt + eligible.discard((x, y)) + res = min( + dp(x + 1, y, cnt), + dp(x, y + 1, cnt), + dp(x - 1, y, cnt), + dp(x, y - 1, cnt), + ) + eligible.add((x, y)) + return res + + m, n = len(grid), len(grid[0]) + eligible = set(product(range(m), range(n))) + return dp(0, 0, 0) < health + + +if __name__ == "__main__": + obj = Solution() + print( + obj.findSafeWalk( + grid=[[0, 1, 0, 0, 0], [0, 1, 0, 1, 0], [0, 0, 0, 1, 0]], health=1 + ) + ) + print( + obj.findSafeWalk( + grid=[ + [0, 1, 1, 0, 0, 0], + [1, 0, 1, 0, 0, 0], + [0, 1, 1, 1, 0, 1], + [0, 0, 1, 0, 1, 0], + ], + health=3, + ) + ) + print(obj.findSafeWalk(grid=[[1, 1, 1], [1, 0, 1], [1, 1, 1]], health=5))