Skip to main content
Advanced

Swim in Rising Water

Prerequisites and earlier practice
Learn These Concepts Before SolvingStudy highlighted concepts first
→Binary Heaps & Top-K→Dijkstra’s Algorithm→Minimax PathsComing soon→Grid GraphComing soon
1. Problem Prompt & Practice

Read & Attempt the Question First

You are given an n × n integer grid where each square (r, c) has a distinct ground elevation from 0 to n² − 1. At time t, water across the entire grid has depth t. You may swim 4-directionally between adjacent squares in zero time as long as both squares have elevation ≤ t. Starting at (0, 0), return the earliest time t at which you can reach (n − 1, n − 1).

Input: grid = [[0, 6, 7], [1, 5, 8], [2, 4, 3]]
Output: 4

Explanation: At t = 3, the goal (2, 2) with height 3 is underwater, yet every 4-directional route from (0, 0) is blocked by heights 6, 5, 8, or 4. At t = 4, square (2, 1) opens and 0 → 1 → 2 → 4 → 3 connects immediately.

2. BigOCast Visual Solution

BigOCast Studio
3. Interactive State Simulator

Interactive Rising Water & Min-Heap Simulator

Switch between the Min-Heap Trace and the Water Slider (t) on the 3×3 or 5×5 elevation grid to watch why height 4 at (2, 1) is the true bottleneck.

At t = 3, the finish cell (elevation 3) is underwater — yet blocked by elevation 4 at (2, 1)! Path opens at t = 4.

Step 1 of 6 · Current water level: t = 0Start (0,0) → Goal (2,2)
START0best: 0
(0,1)6best: ∞
(0,2)7best: ∞
(1,0)1best: ∞
(1,1)5best: ∞
(1,2)8best: ∞
(2,0)2best: ∞
(2,1)4best: ∞
GOAL3best: ∞

Algorithm State Inspector

Initialize best[0][0] = 0 and push (0, 0, 0) onto the min-heap.

Min-Heap Queue (level, row, col)1 entries
(0, 0, 0)
Key Minimax Invariant: Standard Dijkstra relaxes with cost + weight. Here, swimming is instant once water reaches height t, so path cost is max(level, grid[nr][nc]) — still monotonically non-decreasing, which is why Dijkstra’s greedy first-pop guarantee holds!
4. Step-by-Step Solution & Python Code

Why This Algorithm Solves Swim in Rising Water Optimally

Why Underwater Does Not Mean Reachable

In our 3 × 3 grid, (2, 2) sits at elevation 3. At t = 3, water covers (0, 0), (1, 0), (2, 0), and (2, 2) — yet (2, 2) is an isolated puddle! Every route out of the left column hits the ridge 6, 5, or 4. Only when t = 4 submerges (2, 1) does a continuous 4-way corridor open from start to finish.

Replacing + With max Inside Dijkstra

Standard Dijkstra relaxes edges using candidate = cost + weight. Here, water depth does not accumulate; crossing a cell only requires the water to be at least as high as that cell:

candidate = max(level, grid[nr][nc])

Because max(level, grid[nr][nc]) >= level is monotonically non-decreasing, no waiting heap entry with water level ≥ 4 can ever later discover a path with water level < 4.

Clean Python Solution

from heapq import heappop, heappush


def swim_in_water(grid: list[list[int]]) -> int:
    n = len(grid)
    best = [[float("inf")] * n for _ in grid]
    best[0][0] = grid[0][0]
    heap = [(grid[0][0], 0, 0)]
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    while heap:
        level, r, c = heappop(heap)
        if level != best[r][c]:
            continue
        if (r, c) == (n - 1, n - 1):
            return level

        for dr, dc in directions:
            nr, nc = r + dr, c + dc
            if not (0 <= nr < n and 0 <= nc < n):
                continue
            candidate = max(level, grid[nr][nc])
            if candidate < best[nr][nc]:
                best[nr][nc] = candidate
                heappush(heap, (candidate, nr, nc))

    raise ValueError("Grid must be non-empty")
  • Time Complexity: O(n² log n) — each of the n² cells is settled once and pushes up to 4 neighbors; log(n²) = 2 log n.
  • Space Complexity: O(n²) for best and the min-heap.
  • Alternatives: Binary Search on t + BFS (O(n² log n)), or sorting cells by elevation + Union-Find (O(n² log n)).

More Visual Question Walkthroughs

All Questions →