返回

寻径问道,解开二叉树路径总和之谜

前端

导言

在浩瀚的算法世界中,二叉树作为一种经典的数据结构,以其简洁高效的特性而备受推崇。而二叉树路径总和问题更是算法竞赛中的常客,考验着算法工程师们的基本功底。

问题定义

给定一棵二叉树的根节点 root 和一个整数 targetSum,求出从根节点到叶节点的路径中,所有路径的和等于 targetSum 的路径条数。

递归算法

递归,作为算法设计中常用的技巧,在解决二叉树路径总和问题中也能大显身手。递归算法的思路如下:

  • 从根节点开始,递归地求解其左右子树的路径总和。
  • 对于每个子树,如果其路径总和等于 targetSum,则路径条数加 1。
  • 返回当前根节点的路径条数。
public int pathSum(TreeNode root, int targetSum) {
    if (root == null) {
        return 0;
    }
    int res = pathSumFrom(root, targetSum);
    res += pathSum(root.left, targetSum);
    res += pathSum(root.right, targetSum);
    return res;
}

private int pathSumFrom(TreeNode root, int targetSum) {
    if (root == null) {
        return 0;
    }
    int res = 0;
    if (root.val == targetSum) {
        res++;
    }
    res += pathSumFrom(root.left, targetSum - root.val);
    res += pathSumFrom(root.right, targetSum - root.val);
    return res;
}

深度优先搜索

深度优先搜索(DFS)算法也是解决二叉树路径总和问题的有效方法。DFS 的思路如下:

  • 从根节点开始,将其压入栈中。
  • 循环执行以下步骤,直到栈为空:
    • 弹出栈顶元素 node
    • 计算从根节点到 node 的路径总和 pathSum
    • 如果 pathSum 等于 targetSum,则路径条数加 1。
    • node 的左右子树压入栈中。
public int pathSum(TreeNode root, int targetSum) {
    if (root == null) {
        return 0;
    }
    int res = 0;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        int pathSum = node.val;
        if (pathSum == targetSum) {
            res++;
        }
        if (node.left != null) {
            node.left.val += node.val;
            stack.push(node.left);
        }
        if (node.right != null) {
            node.right.val += node.val;
            stack.push(node.right);
        }
    }
    return res;
}

实例与分析

我们以一棵简单二叉树为例,其节点值分别为 [10, 5, -3, 3, 2, null, 11, 3, -2, null, 1]:

          10
         /  \
        5   -3
       / \    / \
      3   2  -2   1
      \   \
      3   -2
      \
      1

递归算法

从根节点 10 开始递归:

  • 左子树的路径总和:3 + 2 + 3 + 1 = 9
  • 右子树的路径总和:-2 + 1 = -1
  • 当前根节点的路径总和:10
  • 路径条数:0

深度优先搜索算法

从根节点 10 开始遍历:

  • 从栈中弹出根节点 10,路径总和:10
  • 路径条数:1
  • 将左右子树压入栈中
  • 从栈中弹出左子树节点 5,路径总和:15
  • 路径条数:1
  • 将左右子树压入栈中
  • ...

通过继续遍历,我们可以得到最终路径条数为 3。

总结

二叉树路径总和算法的求解涉及递归和深度优先搜索两种方法。这两种方法各有优缺点,递归算法实现简单直观,而深度优先搜索算法效率更高。在实际应用中,开发者可以根据具体情况选择最适合的方法。

掌握了二叉树路径总和算法,不仅可以加深我们对二叉树数据结构的理解,还可以为解决更复杂的数据结构问题奠定基础。算法学习的道路漫漫其修远,但只要我们不断探索和实践,终能登堂入室,领略算法之美。