# **Leetcode筆記(Pacific Atlantic Water Flow)** :::info :information_source: 題目 : Pacific Atlantic Water Flow, 類型 : graph , 等級 : medium 日期 : 2023/04/15,2023/05/18,2023/07/13 ::: ### 嘗試 2023/05/18 ```python class Solution: def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: m, n = len(heights), len(heights[0]) pac, atl = [[False] * n for i in range(m)], [[False] * n for i in range(m)] dirs =[(1, 0), (-1, 0), (0, 1), (0, -1)] def dfs(r, c, sea, prev): if r < 0 or r >= m or c < 0 or c >= n or heights[r][c] < prev or sea[r][c]: return False sea[r][c] = True for dr, dc in dirs: nr, nc = r + dr, c + dc if dfs(nr, nc, sea, heights[r][c]): # 這裡其實可以省略 因為重點在標記sea[r][c] return True # 跳出這個迴圈 到starting去執行下一步 return False # 從邊出發(starting) for r in range(m): dfs(r, 0, pac, 0) # 左 dfs(r, n - 1, atl, 0) # 右 for c in range(n): dfs(0, c, pac, 0) # 上 dfs(m - 1, c, atl, 0) # 下 res = [] # 兩邊皆可流通 for r in range(m): for c in range(n): if pac[r][c] and atl[r][c]: res.append([r, c]) return res ``` 2023/07/13 從pac和atl的每個點去做dfs,從該點進入matrix,看能到達哪一點(代表那點和這個海洋互通) 同時也要記錄pre,這條dfs路徑的高度必須不停遞增,才可以通 ```python class Solution: def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: m, n = len(heights), len(heights[0]) dirs = [(0, 1), (1, 0), (0, -1), (-1, 0)] pac, atl = [[False] * n for _ in range(m)], [[False] * n for _ in range(m)] res = [] def dfs(r, c, sea, pre): if r < 0 or c < 0 or r >= m or c >= n or sea[r][c] or heights[r][c] < pre: return sea[r][c] = True for dr, dc in dirs: nr, nc = r + dr, c + dc dfs(nr, nc, sea, heights[r][c]) return for r in range(m): dfs(r, 0, pac, 0) dfs(r, n - 1, atl, 0) for c in range(n): dfs(0, c, pac, 0) dfs(m - 1, c, atl, 0) for r in range(m): for c in range(n): if pac[r][c] and atl[r][c]: res.append([r, c]) return res ``` --- ### **優化** 時間複雜度為 $O(mn)$,其中 $m$ 是矩陣的行數,$n$ 是矩陣的列數。每個格子最多只會被遍歷一次,因此時間複雜度為線性的。 空間複雜度為 $O(mn)$,主要是用來存儲訪問數組、太平洋和大西洋的可達情況。 ```python class Solution: def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]: ROW, COL = len(heights), len(heights[0]) # [[False] * 行 for i in range(列)] pac = [[False] * COL for i in range(ROW)] atl = [[False] * COL for i in range(ROW)] def dfs(r, c, visit, pre_height): if (r < 0 or c < 0 or r == ROW or c == COL or visit[r][c] or pre_height > heights[r][c]): return visit[r][c] = True # 可以流通 # 往四個方向 dfs(r + 1, c, visit, heights[r][c]) dfs(r - 1, c, visit, heights[r][c]) dfs(r, c + 1, visit, heights[r][c]) dfs(r, c - 1, visit, heights[r][c]) # dfs(row, column, ocean, previous height) # 最左和最上出發往中間 代表為pacific # 最右和最下出發往中間 代表為atlantic # starting for r in range(ROW): dfs(r, 0, pac, heights[r][0]) dfs(r, COL - 1, atl, heights[r][COL - 1]) for c in range(COL): dfs(0, c, pac, heights[0][c]) dfs(ROW - 1, c, atl, heights[ROW - 1][c]) # 確認有誰是true res = [] for r in range(ROW): for c in range(COL): if pac[r][c] and atl[r][c]: res.append([r, c]) return res ``` --- **:warning: 錯誤語法** :::warning ::: **:thumbsup:學習** :::success graph網格,基本上都用dfs,用一個index紀錄 [[False] * 行 for i in range(列)] ::: **思路** **講解連結** https://www.youtube.com/watch?v=s-VkcjHqkGI Provided by. NeetCode ###### tags: `graph` `medium` `leetcode`