返回

LeetCode 刷题之 DFS 算法深入浅出讲解

前端

DFS(深度优先搜索)算法是一种非常重要的算法,广泛应用于树和图的遍历中。与 BFS(广度优先搜索)算法相比,DFS 具有以下优点:

  • 可以找到最短路径。
  • 可以找到所有路径。
  • 可以找到环。
  • 可以找到联通分量。

在 LeetCode 刷题中,DFS 算法也是经常遇到的。本文将通过几个 LeetCode 题目,详细讲解 DFS 算法的原理和应用。

LeetCode 104. 二叉树的最大深度

给定一个二叉树,求其最大深度。

        3
       / \
      9  20
        /  \
       15   7

最大深度是指从根节点到最深叶节点的路径上的节点数。上图中,最大深度为 3。

public int maxDepth(TreeNode root) {
  if (root == null) {
    return 0;
  }

  int leftDepth = maxDepth(root.left);
  int rightDepth = maxDepth(root.right);

  return Math.max(leftDepth, rightDepth) + 1;
}

LeetCode 112. 路径总和

给定一个二叉树和一个目标和,判断是否存在从根节点到叶节点的路径,使得路径上的节点值之和等于给定的目标和。

        5
       / \
      4   8
     /   / \
    11  13  4
   /  \      \
  7    2      1

对于上图,如果目标和为 22,则存在路径 5 -> 4 -> 11 -> 2,路径上的节点值之和为 22。

public boolean hasPathSum(TreeNode root, int targetSum) {
  if (root == null) {
    return false;
  }

  if (root.left == null && root.right == null) {
    return root.val == targetSum;
  }

  return hasPathSum(root.left, targetSum - root.val) ||
         hasPathSum(root.right, targetSum - root.val);
}

LeetCode 130. 被围绕的区域

给定一个由 'X' 和 'O' 组成的矩阵,将所有被 'X' 包围的 'O' 区域替换为 'X'。

X X X X
X O O X
X X O X
X O X X

替换后,矩阵变为:

X X X X
X X X X
X X X X
X X X X
public void solve(char[][] board) {
  if (board == null || board.length == 0 || board[0].length == 0) {
    return;
  }

  int m = board.length;
  int n = board[0].length;

  // 从边界开始进行 DFS,将所有与边界相连的 'O' 标记为 'M'。
  for (int i = 0; i < m; i++) {
    if (board[i][0] == 'O') {
      dfs(board, i, 0);
    }
    if (board[i][n - 1] == 'O') {
      dfs(board, i, n - 1);
    }
  }

  for (int j = 0; j < n; j++) {
    if (board[0][j] == 'O') {
      dfs(board, 0, j);
    }
    if (board[m - 1][j] == 'O') {
      dfs(board, m - 1, j);
    }
  }

  // 将所有 'O' 替换为 'X',将所有 'M' 替换为 'O'。
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      if (board[i][j] == 'O') {
        board[i][j] = 'X';
      } else if (board[i][j] == 'M') {
        board[i][j] = 'O';
      }
    }
  }
}

private void dfs(char[][] board, int i, int j) {
  if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O') {
    return;
  }

  // 将 'O' 标记为 'M'。
  board[i][j] = 'M';

  // 继续对相邻的 'O' 进行 DFS。
  dfs(board, i - 1, j);
  dfs(board, i + 1, j);
  dfs(board, i, j - 1);
  dfs(board, i, j + 1);
}

结语

DFS 算法是一种非常重要的算法,广泛应用于树和图的遍历中。通过 LeetCode 刷题,你可以掌握 DFS 算法的原理和应用,为解决更复杂的算法问题打下坚实的基础。