↓快轉到主要內容
  1. LeetCode/

LeetCode 778: Swim in Rising Water

·2 分鐘· ·
LeetCode Hard Graph Dijkstra Binary-Search
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-04-18 來源:Day 7 learning note

學習脈絡
#

這篇是從 learning note 裡該 LeetCode 題目的段落重新整理出來的版本。我保留當天筆記中的修正點、比較點、容易犯錯的地方,並移除同一天其他非 LeetCode 主題,避免文章內容混題。

筆記中提到的相關提醒
#

    1. Explain why LC 778 is a Dijkstra variant.

當天筆記摘錄
#

Problem 1 - LC 778 Swim in Rising Water
#

  • Status: Completed; prefer direct Dijkstra wording in interviews.
  • Pattern: Dijkstra variant on grid.
  • Graph type: Grid graph; each cell is a node.
  • Path cost: Maximum elevation value along the path.
  • State in heap: (time_required, row, col).
  • Return condition: Return when bottom-right cell is popped from heap.

Interview-Ready Explanation
#

This is a shortest-path problem on a grid graph. The cost of a path is the maximum elevation value of any cell on that path, because at time t, I can only enter cells with elevation <= t. Dijkstra works because when I extend a path to a neighbor, the new cost is max(current_time, grid[nr][nc]), so the path cost never decreases. I store (time_required, row, col) in a min-heap. When a cell is popped for the first time, its minimum required time is finalized. When the destination is popped, I return that time.

Preferred Implementation Detail
#

Prefer pushing the full path cost:

new_time = max(time, grid[nr][nc])
heappush(heap, (new_time, nr, nc))

This matches the Dijkstra explanation directly.

正確解法
#

上面的筆記保留了推理脈絡和當天需要修正的點。下面是我會提交的版本。

from heapq import heappop, heappush
from typing import List

class Solution:
    def swimInWater(self, grid: List[List[int]]) -> int:
        n = len(grid)
        seen = [[False] * n for _ in range(n)]
        heap = [(grid[0][0], 0, 0)]
        dirs = [(1,0), (-1,0), (0,1), (0,-1)]

        while heap:
            time, r, c = heappop(heap)
            if seen[r][c]:
                continue
            seen[r][c] = True
            if (r, c) == (n - 1, n - 1):
                return time
            for dr, dc in dirs:
                nr, nc = r + dr, c + dc
                if 0 <= nr < n and 0 <= nc < n and not seen[nr][nc]:
                    heappush(heap, (max(time, grid[nr][nc]), nr, nc))
        return -1

複雜度
#

Time O(n^2 log n), Space O(n^2).

要特別避免的錯誤
#

  • Summing elevations.
  • Using plain BFS despite different required times.

面試口說整理
#

先講清楚 state definition,再說 transition 為什麼維持這個 state。只要這題有 loop direction、狀態壓縮、或題型相似但 answer shape 不同的地方,就要主動講出來,因為那通常就是這類題最容易出錯的點。

相關文章

LeetCode 1203: Sort Items by Groups Respecting Dependencies
·2 分鐘
LeetCode Hard Graph Topological-Sort
LeetCode 1203 解題筆記,依照原始 learning note 重新整理
LeetCode 1514: Path with Maximum Probability
·1 分鐘
LeetCode Medium Graph Dijkstra Shortest-Path Heap
LeetCode 1514 解題筆記:機率相乘只會變小,所以 Dijkstra 可以直接用;剪枝要用 <=
LeetCode 1793: Maximum Score of a Good Subarray
·1 分鐘
LeetCode Hard Two-Pointers Greedy Binary-Search Array Monotonic-Stack
LeetCode 1793 解題筆記:從 k 往兩邊擴張,每次往鄰居比較大的那一邊走,讓每個長度的最小值盡量大;到邊界時只能往另一邊
LeetCode 1782: Count Pairs Of Nodes
·2 分鐘
LeetCode Hard Two-Pointers Graph Sorting Hash-Table Counting
LeetCode 1782 解題筆記:先用排序後的度數 + 對撞指針數 deg[a] + deg[b] > q 的配對,再對有共用邊的配對修正多算的部分
LeetCode 2009: Minimum Number of Operations to Make Array Continuous
·1 分鐘
LeetCode Hard Sliding-Window Hash-Table Binary-Search Array
LeetCode 2009 解題筆記:最後的陣列是長度 n 的連續整數;去重排序後,用滑動視窗找值域寬度 <= n - 1 的最多不同值,其他都要改
LeetCode 2106: Maximum Fruits Harvested After at Most K Steps
·1 分鐘
LeetCode Hard Sliding-Window Prefix-Sum Binary-Search Array
LeetCode 2106 解題筆記:採到的一定是連續一段水果;走完 [L, R] 的最少步數是 (R - L) + min(|start - L|, |R - start|),在水果陣列上用滑動視窗