You are given an m x n binary matrix grid and an integer health.
You start on the upper-left corner (0, 0) and would like to get to the lower-right corner (m - 1, n - 1).
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[i][j] = 1 are considered unsafe and reduce your health by 1.
Return true if you can reach the final cell with a health value of 1 or more, and false otherwise.
Example 1:
Input: grid = [[0,1,0,0,0],[0,1,0,1,0],[0,0,0,1,0]], health = 1
Output: true
Explanation:
The final cell can be reached safely by walking along the gray cells below.

Example 2:
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 = 3
Output: false
Explanation:
A minimum of 4 health points is needed to reach the final cell safely.

Example 3:
Input: grid = [[1,1,1],[1,0,1],[1,1,1]], health = 5
Output: true
Explanation:
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.
Constraints:
m == grid.lengthn == grid[i].length1 <= m, n <= 502 <= m * n1 <= health <= m + ngrid[i][j] is either 0 or 1.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The goal is to find a safe path through a grid, avoiding dangerous spots. The brute-force method explores every single possible path from the start to the end. It's like trying every route you can think of until you find one that's safe.
Here's how the algorithm would work step-by-step:
def find_safe_walk(grid):
if not grid:
return []
rows = len(grid)
cols = len(grid[0])
start = (0, 0)
end = (rows - 1, cols - 1)
safe_paths = []
path = []
def is_safe(row_index, column_index):
return 0 <= row_index < rows and 0 <= column_index < cols and grid[row_index][column_index] == 1
def find_all_paths(current_row_index, current_column_index, current_path):
if (current_row_index, current_column_index) == end:
safe_paths.append(current_path[:] + [(current_row_index, current_column_index)])
return
# Define possible moves: right, down, left, up
possible_moves = [(0, 1), (1, 0), (0, -1), (-1, 0)]
for row_delta, column_delta in possible_moves:
next_row_index = current_row_index + row_delta
next_column_index = current_column_index + column_delta
# Validate next step if it is safe and not already in the current path
if is_safe(next_row_index, next_column_index) and (next_row_index, next_column_index) not in current_path:
# Add current location to the path
current_path.append((current_row_index, current_column_index))
find_all_paths(next_row_index, next_column_index, current_path)
# Backtrack to explore other paths
current_path.pop()
# Initiate brute force searching
find_all_paths(0, 0, path)
if safe_paths:
return safe_paths[0]
else:
return []The goal is to find the safest path through a grid where some spots are dangerous. Instead of exploring every possible path, we'll use a method that focuses on gradually building the safest route, one step at a time, ensuring each step maximizes safety.
Here's how the algorithm would work step-by-step:
def find_safe_walk(grid):
number_of_rows = len(grid)
number_of_columns = len(grid[0])
start_row = 0
start_column = 0
end_row = number_of_rows - 1
end_column = number_of_columns - 1
# Risk score is the value in the grid itself.
risk_scores = grid
current_row = start_row
current_column = start_column
path = [(current_row, current_column)]
while current_row != end_row or current_column != end_column:
# Find the safest neighbor. This determines next step.
neighbors = []
if current_row > 0:
neighbors.append((current_row - 1, current_column))
if current_row < number_of_rows - 1:
neighbors.append((current_row + 1, current_column))
if current_column > 0:
neighbors.append((current_row, current_column - 1))
if current_column < number_of_columns - 1:
neighbors.append((current_row, current_column + 1))
safest_neighbor = None
lowest_risk = float('inf')
for neighbor_row, neighbor_column in neighbors:
if risk_scores[neighbor_row][neighbor_column] < lowest_risk:
lowest_risk = risk_scores[neighbor_row][neighbor_column]
safest_neighbor = (neighbor_row, neighbor_column)
# If no safe neighbors, return current path.
if safest_neighbor is None:
return path
# Update the current position to the safest neighbor
current_row, current_column = safest_neighbor
path.append((current_row, current_column))
return path| Case | How to Handle |
|---|---|
| Null or empty grid | Return an empty path or an appropriate error code to indicate no path exists. |
| Grid with only one cell | Return the single cell if it's 'safe', otherwise return an empty path. |
| Grid where no safe path exists | The algorithm should terminate gracefully and return an empty path or an error indicator. |
| Very large grid (potential memory issues) | Consider an iterative approach to pathfinding to avoid stack overflow and monitor memory usage. |
| Grid with all cells marked as unsafe | The algorithm should correctly identify that no path is possible and return an empty path. |
| Integer overflow when calculating risk or safety | Use appropriate data types (e.g., long) or modulo operations to prevent overflows. |
| Grid where the starting or ending cell is unsafe | Return an empty path immediately if the start or end is unsafe. |
| Cyclical paths in the grid leading to infinite loops | Implement a visited set to avoid re-visiting the same cells during path exploration. |