You are given a 0-indexed 2D integer array grid of size m x n which represents a field. Each cell has one of three values:
0 represents grass
1 represents fire
2 represents a wall that you and fire cannot pass through
You are situated in the top-left cell(0, 0), and you want to travel to the safehouse at the bottom-right cell(m - 1, n - 1). Every minute, you may move to an adjacent grass cell. After your move, every fire cell will spread to all adjacent cells that are not walls.
Return the maximum number of minutes that you can stay in your initial position before moving while still safely reaching the safehouse. If this is impossible, return -1. If you can always reach the safehouse regardless of the minutes stayed, return 10^9.
Note that even if the fire spreads to the safehouse immediately after you have reached it, it will be counted as safely reaching the safehouse.
A cell is adjacent to another cell if the former is directly north, east, south, or west of the latter (i.e., their sides are touching).
The key insight is to use binary search on the answer space - if we can escape with delay T, we can escape with delay T-1. Best approach combines binary search with BFS simulation. Time: O(log(mn) × mn), Space: O(mn)
Common Approaches
✓
Memoization
⏱️ Time: N/A
Space: N/A
Dp 1d
⏱️ Time: N/A
Space: N/A
Binary Search on Answer
⏱️ Time: O(log(mn) × mn)
Space: O(m × n)
Since if we can escape with delay T, we can escape with any delay < T, we can binary search on the answer. For each candidate delay, use BFS to check if escape is possible.
Brute Force Simulation
⏱️ Time: O(k × m × n)
Space: O(m × n)
For each possible delay time, simulate the fire spreading and check if we can still reach the safehouse. This approach tests all delay times sequentially until we find the maximum valid one.
Algorithm Steps — Algorithm Steps
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct {
int r, c, t;
} State;
bool canEscape(int** grid, int m, int n, int delay, int** initialFires, int fireCount) {
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
// Initialize fireTime array
int** fireTime = (int**)malloc(m * sizeof(int*));
for (int i = 0; i < m; i++) {
fireTime[i] = (int*)malloc(n * sizeof(int));
for (int j = 0; j < n; j++) {
fireTime[i][j] = -1;
}
}
// BFS for fire spread
State* fireQueue = (State*)malloc(m * n * sizeof(State));
int fireHead = 0, fireTail = 0;
for (int i = 0; i < fireCount; i++) {
fireTime[initialFires[i][0]][initialFires[i][1]] = 0;
fireQueue[fireTail++] = (State){initialFires[i][0], initialFires[i][1], 0};
}
while (fireHead < fireTail) {
State curr = fireQueue[fireHead++];
for (int d = 0; d < 4; d++) {
int nr = curr.r + directions[d][0];
int nc = curr.c + directions[d][1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n &&
grid[nr][nc] != 2 && fireTime[nr][nc] == -1) {
fireTime[nr][nc] = curr.t + 1;
fireQueue[fireTail++] = (State){nr, nc, curr.t + 1};
}
}
}
free(fireQueue);
if (fireTime[0][0] != -1 && fireTime[0][0] <= delay) {
for (int i = 0; i < m; i++) free(fireTime[i]);
free(fireTime);
return false;
}
// BFS for player path
State* queue = (State*)malloc(m * n * sizeof(State));
bool** visited = (bool**)malloc(m * sizeof(bool*));
for (int i = 0; i < m; i++) {
visited[i] = (bool*)calloc(n, sizeof(bool));
}
int head = 0, tail = 0;
queue[tail++] = (State){0, 0, delay};
visited[0][0] = true;
while (head < tail) {
State curr = queue[head++];
if (curr.r == m-1 && curr.c == n-1) {
for (int i = 0; i < m; i++) {
free(fireTime[i]);
free(visited[i]);
}
free(fireTime);
free(visited);
free(queue);
return true;
}
for (int d = 0; d < 4; d++) {
int nr = curr.r + directions[d][0];
int nc = curr.c + directions[d][1];
if (nr >= 0 && nr < m && nc >= 0 && nc < n &&
!visited[nr][nc] && grid[nr][nc] != 2 &&
(fireTime[nr][nc] == -1 || fireTime[nr][nc] > curr.t + 1)) {
visited[nr][nc] = true;
queue[tail++] = (State){nr, nc, curr.t + 1};
}
}
}
for (int i = 0; i < m; i++) {
free(fireTime[i]);
free(visited[i]);
}
free(fireTime);
free(visited);
free(queue);
return false;
}
int solution(int** grid, int m, int n) {
int** initialFires = (int**)malloc(m * n * sizeof(int*));
int fireCount = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
initialFires[fireCount] = (int*)malloc(2 * sizeof(int));
initialFires[fireCount][0] = i;
initialFires[fireCount][1] = j;
fireCount++;
}
}
}
if (grid[0][0] != 0 || grid[m-1][n-1] == 2) {
for (int i = 0; i < fireCount; i++) free(initialFires[i]);
free(initialFires);
return -1;
}
if (!canEscape(grid, m, n, 0, initialFires, fireCount)) {
for (int i = 0; i < fireCount; i++) free(initialFires[i]);
free(initialFires);
return -1;
}
int left = 0, right = m * n, result = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (canEscape(grid, m, n, mid, initialFires, fireCount)) {
result = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
for (int i = 0; i < fireCount; i++) free(initialFires[i]);
free(initialFires);
return result >= m + n ? 1000000000 : result;
}
int main() {
char line[10000];
fgets(line, sizeof(line), stdin);
int m = 0, n = 0;
int** grid = NULL;
char* ptr = line + 1;
while (*ptr) {
if (*ptr == '[') {
m++;
if (grid == NULL) {
char* temp = ptr + 1;
n = 1;
while (*temp && *temp != ']') {
if (*temp == ',') n++;
temp++;
}
grid = (int**)malloc(100 * sizeof(int*));
}
grid[m-1] = (int*)malloc(n * sizeof(int));
ptr++;
for (int j = 0; j < n; j++) {
grid[m-1][j] = atoi(ptr);
while (*ptr && *ptr != ',' && *ptr != ']') ptr++;
if (*ptr == ',') ptr++;
}
}
ptr++;
}
printf("%d\n", solution(grid, m, n));
for (int i = 0; i < m; i++) free(grid[i]);
free(grid);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
n
2n
⚡ Linearithmic
Space Complexity
n
2n
⚡ Linearithmic Space
23.5K Views
MediumFrequency
~35 minAvg. Time
847 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.