from typing import List, Set, Tuple
class Solution:
def pacificAtlantic(self, heights: List[List[int]]) -> List[List[int]]:
"""
找出所有既能流向太平洋也能流向大西洋的单元格坐标。
Args:
heights: 表示单元格高度的二维列表。
Returns:
一个包含所有满足条件的单元格坐标 [r, c] 的列表。
"""
if not heights or not heights[0]:
return []
rows = len(heights)
cols = len(heights[0])
# 记录能流向太平洋和大西洋的单元格集合
pac_reachable: Set[Tuple[int, int]] = set()
atl_reachable: Set[Tuple[int, int]] = set()
# 方向数组,方便遍历邻居 (右, 左, 下, 上)
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
def dfs(r: int, c: int, visited: Set[Tuple[int, int]], prev_height: int):
"""
深度优先搜索函数,从边界向内陆标记可达单元格。
Args:
r: 当前行。
c: 当前列。
visited: 当前正在标记的集合 (pac_reachable 或 atl_reachable)。
prev_height: 上一个单元格的高度。
"""
# 1. 边界条件和剪枝条件检查
# a. 超出边界
if not (0 <= r < rows and 0 <= c < cols):
return
# b. 已经被访问过 (对于当前目标大洋)
if (r, c) in visited:
return
# c. 高度条件:水无法从 prev_height 流向 heights[r][c] (反向搜索)
if heights[r][c] < prev_height:
return
# 2. 标记当前单元格为可达
visited.add((r, c))
# 3. 递归探索四个方向的邻居
current_height = heights[r][c]
for dr, dc in directions:
nr, nc = r + dr, c + dc
# 将当前高度作为下一次递归的 prev_height
dfs(nr, nc, visited, current_height)
# --- 主流程 ---
# 4. 从太平洋边界 (顶部和左侧) 开始 DFS
for c in range(cols):
dfs(0, c, pac_reachable, heights[0][c]) # 顶部边界
for r in range(rows):
dfs(r, 0, pac_reachable, heights[r][0]) # 左侧边界
# 5. 从大西洋边界 (底部和右侧) 开始 DFS
for c in range(cols):
dfs(rows - 1, c, atl_reachable, heights[rows - 1][c]) # 底部边界
for r in range(rows):
dfs(r, cols - 1, atl_reachable, heights[r][cols - 1]) # 右侧边界
# 6. 找出交集
result = []
for r in range(rows):
for c in range(cols):
# 如果一个单元格同时在两个可达集合中
if (r, c) in pac_reachable and (r, c) in atl_reachable:
result.append([r, c])
return result
# 示例用法
# solution = Solution()
# heights1 = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
# print(solution.pacificAtlantic(heights1))
# 输出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]] (顺序可能不同)
# heights2 = [[1]]
# print(solution.pacificAtlantic(heights2))
# 输出: [[0,0]]
417. 太平洋大西洋水流问题
最新推荐文章于 2025-05-04 22:46:35 发布