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

LeetCode 417: Pacific Atlantic Water Flow

·1 分鐘· ·
LeetCode Medium Array Depth-First-Search Breadth-First-Search Matrix
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-10-30

  • 提交紀錄:Runtime Error ×4 → Wrong Answer → Runtime Error ×2 → Wrong Answer ×5 → Time Limit Exceeded → Runtime Error → Time Limit Exceeded → Runtime Error ×2 → Wrong Answer ×3 → Accepted ×2

解題思路
#

從每一格出發往下流去找海,最壞是 O((mn)²)。反過來(BFS 模板三,多源):從太平洋的邊(第一列、第一欄)出發,往不比自己低的格子走,走得到的就是能流進太平洋的格子;大西洋(最後一列、最後一欄)同理。兩個集合的交集就是答案,每個海各 O(mn)。

我的嘗試
#

這題提交了 22 次:

  • 下午先寫「每一格往下流找海」的 DFS,大西洋邊界的判斷把列數和欄數對調(i == len(heights[0]) - 1),非正方形時判斷錯誤;修好之後每一格都重新 DFS,TLE 了兩次。
  • 晚上改成從海邊反著走,又錯在三個地方:條件寫成 <= prev 就停,起點自己的高度等於 prev,一開始就被擋掉([[1]] 回傳 []);visit.add([r, c]) 放了 list(TypeError);最右邊那一欄放進了太平洋的集合。三個都改掉才 AC。

正確解法
#

class Solution:
    def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
        m, n = len(heights), len(heights[0])
        def reach(starts):
            seen = set(starts)
            stack = list(starts)
            while stack:
                i, j = stack.pop()
                for x, y in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)):
                    if (0 <= x < m and 0 <= y < n and (x, y) not in seen
                            and heights[x][y] >= heights[i][j]):
                        seen.add((x, y))
                        stack.append((x, y))
            return seen
        pacific = reach([(0, j) for j in range(n)] + [(i, 0) for i in range(m)])
        atlantic = reach([(m - 1, j) for j in range(n)] + [(i, n - 1) for i in range(m)])
        return [[i, j] for i, j in pacific & atlantic]

複雜度
#

時間 O(mn),空間 O(mn)。

要特別避免的錯誤
#

  • 反著走時條件是「不比自己低」(>=),一樣高也能流。
  • 起點本身就在集合裡,不能被「比前一格高」的條件擋掉。
  • 太平洋是第一列、第一欄;大西洋是最後一列、最後一欄,不要放錯集合。
  • set 裡要放 tuple,list 不能 hash。

面試口說整理
#

從每一格往下找海太慢,所以我反過來,從兩個海的邊出發,往不比自己低的格子走,分別得到能流進太平洋和大西洋的格子,兩者的交集就是答案。每個海走一次,時間 O(mn)。

相關文章

LeetCode 695: Max Area of Island
·1 分鐘
LeetCode Medium Array Depth-First-Search Breadth-First-Search Union-Find
LeetCode 695 解題筆記:每遇到一個沒走過的 1 就 DFS 整座島,數格子數,取最大值;格子是整數 1,不是字串
LeetCode 733: Flood Fill
·1 分鐘
LeetCode Easy Array Depth-First-Search Breadth-First-Search Matrix
LeetCode 733 解題筆記:從起點 DFS / BFS,四個方向上跟起點原本顏色相同的格子都換成新顏色;新舊顏色相同時直接回傳
LeetCode 463: Island Perimeter
·1 分鐘
LeetCode Easy Array Depth-First-Search Breadth-First-Search Matrix
LeetCode 463 解題筆記:每格陸地貢獻 4 條邊,每跟上方或左方的陸地相鄰一次就少 2 條
LeetCode 133: Clone Graph
·1 分鐘
LeetCode Medium Hash-Table Depth-First-Search Breadth-First-Search Graph
LeetCode 133 解題筆記:DFS 時用雜湊表記住舊節點對應的新節點,遇到已經複製過的就直接回傳,避免無限遞迴;空圖回傳 None
LeetCode 1448: Count Good Nodes in Binary Tree
·1 分鐘
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 1448 解題筆記:DFS 往下傳路徑上的最大值,節點的值大於等於它就是好節點
LeetCode 199: Binary Tree Right Side View
·1 分鐘
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 199 解題筆記:層序遍歷,每一層最右邊的節點就是從右邊看得到的