import heapq
class Solution:
def swimInWater(self, grid):
N = len(grid)
visited = [[False]*N for _ in range(N)]
minHeap = [(grid[0][0], 0, 0)] # (time, x, y)
directions = [(-1,0), (1,0), (0,-1), (0,1)]
while minHeap:
time, x, y = heapq.heappop(minHeap)
if x == N-1 and y == N-1:
return time
if visited[x][y]:
continue
visited[x][y] = True
for dx, dy in directions:
nx, ny = x+dx, y+dy
if 0 <= nx < N and 0 <= ny < N and not visited[nx][ny]:
heapq.heappush(minHeap, (max(time, grid[nx][ny]), nx, ny))
#include <vector>
#include <queue>
#include <utility>
using namespace std;
class Solution {
public:
int swimInWater(vector<vector<int>>& grid) {
int N = grid.size();
vector<vector<bool>> visited(N, vector<bool>(N, false));
priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;
pq.emplace(grid[0][0], 0, 0);
int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
while (!pq.empty()) {
auto [time, x, y] = pq.top(); pq.pop();
if (x == N-1 && y == N-1) return time;
if (visited[x][y]) continue;
visited[x][y] = true;
for (auto& d : dirs) {
int nx = x + d[0], ny = y + d[1];
if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {
pq.emplace(max(time, grid[nx][ny]), nx, ny);
}
}
}
return -1;
}
};
import java.util.*;
class Solution {
public int swimInWater(int[][] grid) {
int N = grid.length;
boolean[][] visited = new boolean[N][N];
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
pq.offer(new int[]{grid[0][0], 0, 0});
int[][] dirs = {{-1,0},{1,0},{0,-1},{0,1}};
while (!pq.isEmpty()) {
int[] curr = pq.poll();
int time = curr[0], x = curr[1], y = curr[2];
if (x == N-1 && y == N-1) return time;
if (visited[x][y]) continue;
visited[x][y] = true;
for (int[] d : dirs) {
int nx = x + d[0], ny = y + d[1];
if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {
pq.offer(new int[]{Math.max(time, grid[nx][ny]), nx, ny});
}
}
}
return -1;
}
}
class MinHeap {
constructor() {
this.heap = [];
}
push([val, x, y]) {
this.heap.push([val, x, y]);
this._bubbleUp(this.heap.length - 1);
}
pop() {
if (this.heap.length === 1) return this.heap.pop();
const top = this.heap[0];
this.heap[0] = this.heap.pop();
this._bubbleDown(0);
return top;
}
_bubbleUp(i) {
while (i > 0) {
let p = Math.floor((i - 1) / 2);
if (this.heap[p][0] <= this.heap[i][0]) break;
[this.heap[p], this.heap[i]] = [this.heap[i], this.heap[p]];
i = p;
}
}
_bubbleDown(i) {
let n = this.heap.length;
while (true) {
let l = 2 * i + 1, r = 2 * i + 2, smallest = i;
if (l < n && this.heap[l][0] < this.heap[smallest][0]) smallest = l;
if (r < n && this.heap[r][0] < this.heap[smallest][0]) smallest = r;
if (smallest === i) break;
[this.heap[i], this.heap[smallest]] = [this.heap[smallest], this.heap[i]];
i = smallest;
}
}
isEmpty() {
return this.heap.length === 0;
}
}
var swimInWater = function(grid) {
const N = grid.length;
const visited = Array.from({length: N}, () => Array(N).fill(false));
const heap = new MinHeap();
heap.push([grid[0][0], 0, 0]);
const dirs = [[-1,0],[1,0],[0,-1],[0,1]];
while (!heap.isEmpty()) {
let [time, x, y] = heap.pop();
if (x === N-1 && y === N-1) return time;
if (visited[x][y]) continue;
visited[x][y] = true;
for (let [dx, dy] of dirs) {
let nx = x + dx, ny = y + dy;
if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {
heap.push([Math.max(time, grid[nx][ny]), nx, ny]);
}
}
}
};
n x n
integer matrix grid
where each cell represents an elevation. Initially, the water level is at 0
and rises by 1
each unit of time. At time t
, you can swim into a cell if its elevation is at most t
. You start at the top-left cell (0, 0)
and want to reach the bottom-right cell (n-1, n-1)
as early as possible. You can move up, down, left, or right to adjacent cells. Return the minimum time t
such that you can reach (n-1, n-1)
.
(current_time, x, y)
, where current_time
is the maximum elevation encountered so far on the path to (x, y)
.visited
matrix to mark cells we've already processed.grid = [ [0, 2], [1, 3] ]
(0,0)
with elevation 0. Push (0, 0, 0)
onto the heap.(0, 0, 0)
. Adjacent cells are (1,0)
(elevation 1) and (0,1)
(elevation 2).(1, 1, 0)
(max(0,1)=1) and (2, 0, 1)
(max(0,2)=2).(1, 1, 0)
. Adjacent cell (1,1)
(elevation 3). Push (3, 1, 1)
(max(1,3)=3).(2, 0, 1)
. No new cells.(3, 1, 1)
. This is the destination. Return 3
.O(4^{N^2})
for an N x N
grid, which is infeasible for large N
.O(\log(N^2))
. Therefore, the total time complexity is O(N^2 \log N)
. Space complexity is O(N^2)
for the visited matrix and the heap.