返回

探秘水流交汇:Leetcode 417. 太平洋大西洋水流问题 - javascript DFS

前端

  1. 初探问题:大陆上的水流交汇

茫茫大陆上,水流纵横交错,在太平洋和大西洋之间蜿蜒穿梭。给定一个非负整数矩阵,我们尝试描绘一片大陆的地形,矩阵中的每个元素代表一个单元格的高度。问题在于,当大雨倾盆时,水会从高处流向低处,那么哪些单元格里的水最终会汇入太平洋,哪些又会汇入大西洋?

2. DFS 深入纵横交错的水流网络

为了解决这个问题,我们引入强大的 DFS(深度优先搜索)算法。DFS 就像是一位脚踏实地的探索者,从一个单元格出发,深入水流交织的网络,步步为营,穷尽所有可能路径。如果从某个单元格出发,水流最终汇入太平洋或大西洋,那么它就是我们要寻找的答案。

3. 踏上 DFS 探索之旅:寻找水流的最终归宿

我们的 DFS 探索之旅将从矩阵的边界单元格开始。太平洋位于矩阵的左边界和上边界,大西洋位于矩阵的右边界和下边界。对于太平洋沿岸的单元格,我们标记它们为太平洋水域;对于大西洋沿岸的单元格,我们标记它们为大西洋水域。

然后,我们从每个边界单元格出发,使用 DFS 算法深入矩阵内部。如果我们遇到一个单元格的高度低于当前单元格,那么水就会从当前单元格流向那个单元格,我们继续前进,深入探索。如果我们遇到一个单元格的高度高于或等于当前单元格,那么水就不会流向那个单元格,我们停止探索。

4. 探索的终点:水流汇入的海洋

经过 DFS 的深入探索,我们最终会找到所有从边界单元格出发,水流最终汇入太平洋或大西洋的单元格。这些单元格就是我们要寻找的答案。

5. JavaScript 实现:算法的代码之美

为了将 DFS 算法应用于这个问题,我们可以使用 JavaScript 语言。JavaScript 代码的简洁性和灵活性,非常适合解决此类动态规划问题。我们将使用一个二维数组来表示矩阵,并使用一个 visited 数组来标记已经访问过的单元格。

function pacificAtlantic(matrix) {
  if (!matrix || matrix.length === 0 || matrix[0].length === 0) {
    return [];
  }
  const m = matrix.length;
  const n = matrix[0].length;
  const pacific = new Array(m).fill(0).map(() => new Array(n).fill(false));
  const atlantic = new Array(m).fill(0).map(() => new Array(n).fill(false));
  const directions = [[-1, 0], [0, 1], [1, 0], [0, -1]];

  const dfs = (row, col, visited, ocean) => {
    if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col]) {
      return;
    }
    visited[row][col] = true;
    ocean[row][col] = true;
    for (const [dx, dy] of directions) {
      const nextRow = row + dx;
      const nextCol = col + dy;
      if (
        nextRow >= 0 &&
        nextRow < m &&
        nextCol >= 0 &&
        nextCol < n &&
        matrix[nextRow][nextCol] >= matrix[row][col]
      ) {
        dfs(nextRow, nextCol, visited, ocean);
      }
    }
  };

  for (let i = 0; i < m; i++) {
    dfs(i, 0, pacific, pacific);
    dfs(i, n - 1, atlantic, atlantic);
  }

  for (let j = 0; j < n; j++) {
    dfs(0, j, pacific, pacific);
    dfs(m - 1, j, atlantic, atlantic);
  }

  const result = [];
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (pacific[i][j] && atlantic[i][j]) {
        result.push([i, j]);
      }
    }
  }

  return result;
}

6. 总结:DFS 算法的强大威力

通过使用 DFS 算法,我们解决了 Leetcode 417. 太平洋大西洋水流问题。DFS 算法凭借其深度优先的探索策略,能够深入复杂的水流网络,找到所有从边界单元格出发,水流最终汇入太平洋或大西洋的单元格。希望这篇博文能够帮助您更好地理解 DFS 算法的应用,并对 Leetcode 417. 太平洋大西洋水流问题有更深入的了解。