417. 太平洋大西洋水流问题

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]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值