Input: grid =[[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0]], health =1Output: trueExplanation:
The final cell can be reached safely by walking along the gray cells below.
Input: 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 =3Output: falseExplanation:
A minimum of 4 health points is needed to reach the final cell safely.
Input: grid =[[1,1,1],[1,0,1],[1,1,1]], health =5Output: trueExplanation:
The final cell can be reached safely by walking along the gray cells below.
Any path that does not go through the cell `(1, 1)`is unsafe since your
health will drop to 0 when reaching the final cell.
We want to reach the bottom-right cell with health ≥ 1, minimizing the number of unsafe cells (1s) we pass through. Each unsafe cell reduces health by 1. We can use a priority queue (min-heap) to always expand the path with the most remaining health, similar to Dijkstra’s algorithm.
import java.util.*;
classSolution {
publicbooleanisSafeWalk(int[][] grid, int health) {
int m = grid.length, n = grid[0].length;
int[][] best =newint[m][n];
for (int[] row : best) Arrays.fill(row, -1);
PriorityQueue<int[]> pq =new PriorityQueue<>((a,b) -> b[0]-a[0]);
pq.offer(newint[]{health, 0, 0});
best[0][0]= health;
int[][] dirs = {{0,1},{1,0},{0,-1},{-1,0}};
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int h = cur[0], x = cur[1], y = cur[2];
if (x == m-1 && y == n-1 && h >= 1) returntrue;
for (int[] d : dirs) {
int nx = x + d[0], ny = y + d[1];
if (nx < 0 || ny < 0 || nx >= m || ny >= n) continue;
int nh = h - grid[nx][ny];
if (nh < 1 || nh <= best[nx][ny]) continue;
best[nx][ny]= nh;
pq.offer(newint[]{nh, nx, ny});
}
}
returnfalse;
}
}
import java.util.PriorityQueue
classSolution {
funisSafeWalk(grid: Array<IntArray>, health: Int): Boolean {
val m = grid.size
val n = grid[0].size
val best = Array(m) { IntArray(n) { -1 } }
val pq = PriorityQueue(compareByDescending<Triple<Int,Int,Int>> { it.first })
pq.add(Triple(health, 0, 0))
best[0][0] = health
val dirs = arrayOf(0 to 1, 1 to 0, 0 to -1, -1 to 0)
while (pq.isNotEmpty()) {
val(h, x, y) = pq.poll()
if (x == m-1&& y == n-1&& h >=1) returntruefor ((dx, dy) in dirs) {
val nx = x + dx
val ny = y + dy
if (nx !in0 until m || ny !in0 until n) continueval nh = h - grid[nx][ny]
if (nh < 1|| nh <= best[nx][ny]) continue best[nx][ny] = nh
pq.add(Triple(nh, nx, ny))
}
}
returnfalse }
}
import heapq
classSolution:
defisSafeWalk(self, grid: list[list[int]], health: int) -> bool:
m, n = len(grid), len(grid[0])
best = [[-1]*n for _ in range(m)]
heap = [(-health, 0, 0)]
best[0][0] = health
while heap:
neg_h, x, y = heapq.heappop(heap)
h =-neg_h
if x == m-1and y == n-1and h >=1:
returnTruefor dx, dy in ((0,1),(1,0),(0,-1),(-1,0)):
nx, ny = x+dx, y+dy
if0<= nx < m and0<= ny < n:
nh = h - grid[nx][ny]
if nh <1or nh <= best[nx][ny]:
continue best[nx][ny] = nh
heapq.heappush(heap, (-nh, nx, ny))
returnFalse
use std::collections::BinaryHeap;
impl Solution {
pubfnis_safe_walk(grid: Vec<Vec<i32>>, health: i32) -> bool {
let m = grid.len();
let n = grid[0].len();
letmut best =vec![vec![-1; n]; m];
letmut heap = BinaryHeap::new();
heap.push((health, 0, 0));
best[0][0] = health;
let dirs = [(0,1),(1,0),(0,-1),(-1,0)];
whilelet Some((h, x, y)) = heap.pop() {
if x == m-1&& y == n-1&& h >=1 { returntrue; }
for (dx, dy) in dirs.iter() {
let nx = x asi32+ dx;
let ny = y asi32+ dy;
if nx <0|| ny <0|| nx >= m asi32|| ny >= n asi32 { continue; }
let nx = nx asusize;
let ny = ny asusize;
let nh = h - grid[nx][ny];
if nh <1|| nh <= best[nx][ny] { continue; }
best[nx][ny] = nh;
heap.push((nh, nx, ny));
}
}
false }
}