616 字
3 分钟
LeetCode-417.太平洋大西洋水流问题

图论#

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

有一个 m × n 的矩形岛屿,与 太平洋大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。

这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heightsheights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度

岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。

返回网格坐标 result2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋


示例 1:

img
输入: heights = [[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]]
输出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]

示例 2:

输入: heights = [[2,1],[1,2]]
输出: [[0,0],[0,1],[1,0],[1,1]]

DFS的解法

思路:

这道题最容易让我们陷入的误区是“正向思维”:遍历每一个格子,分别做 DFS 看它能不能一路走到太平洋和大西洋。这种做法会产生大量重复计算,时间复杂度直接爆炸到 O((M * N)^2)

  • 所以我们逆向思维,太平洋和大西洋倒灌,用表记录能到达的地方,最后比较一下即可,思路不是很复杂

  • 但是有几个注意点:

    1. 这个矩阵需要用循环初始化,不然内部的切片没有初始化,无法使用visited[row][col]
    2. DFS的边界条件注意下,逆着来可能会出错
func pacificAtlantic(heights [][]int) [][]int {
if len(heights) == 0 || len(heights[0]) == 0 {
return nil
}
m, n := len(heights), len(heights[0])
pacific := make([][]bool, m)
atlantic := make([][]bool, m)
for i := 0; i < m; i++ {
pacific[i] = make([]bool, n)
atlantic[i] = make([]bool, n)
}
var dfs func(row, col int, visited [][]bool, pre int)
dfs = func(row, col int, visited [][]bool, pre int) {
if row < 0 || col < 0 || row >= m || col >= n || visited[row][col] || heights[row][col] < pre {
return
}
visited[row][col] = true
dfs(row-1, col, visited, heights[row][col])
dfs(row+1, col, visited, heights[row][col])
dfs(row, col-1, visited, heights[row][col])
dfs(row, col+1, visited, heights[row][col])
}
for i := 0; i < m; i++ {
dfs(i, 0, pacific, heights[i][0])
dfs(i, n-1, atlantic, heights[i][n-1])
}
for j := 0; j < n; j++ {
dfs(0, j, pacific, heights[0][j])
dfs(m-1, j, atlantic, heights[m-1][j])
}
res := [][]int{}
for i:= 0; i < m; i++ {
for j := 0; j < n; j++ {
if atlantic[i][j] && pacific[i][j] {
res = append(res, []int{i, j})
}
}
}
return res
}
LeetCode-417.太平洋大西洋水流问题
https://sheep44044.github.io/posts/算法/图论/leetcode-417太平洋大西洋水流问题/
作者
sheep44044
发布于
2026-03-26
许可协议
CC BY-NC-SA 4.0