力扣第129题-求根节点到叶节点数字之和

194 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

力扣第129题 求根节点到叶节点数字之和 如下所示:

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。

每条从根节点到叶节点的路径都代表一个数字:

  • 例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。

计算从根节点到叶节点生成的 所有数字之和 。

叶节点 是指没有子节点的节点。

示例 1:

输入: root = [1,2,3]
输出: 25
解释:
从根到叶子节点路径 1->2 代表数字 12
从根到叶子节点路径 1->3 代表数字 13
因此,数字总和 = 12 + 13 = 25

一、思路

题目比较容易理解,就是找从根节点到叶子节点的路径表示一个数字(高位至低位),求所有路径的和

例如,下面的这个二叉树就有三条路径。分别为 4 -> 9 -> 54 -> 9 -> 1 以及 4 -> 0,表示的数字分别为 49549140,故和为 495 + 491 + 40 = 1026

image.png

这一题的关键就是要知道:与路径相对应的数字是由什么规则生成的

简单总结一下题目中的重要信息:

  • 路径对应的数字为,高位先遍历,低位后遍历
  • 只有在 叶子节点 才能确定当前路径对应的具体数字,即只在叶子节点才做结算

至于具体的解题步骤的话,这一题很明显可以使用 递归 来实现 深度遍历(至于先选取左孩子还是右孩子,对结果并无影响),大致的步骤如下所示:

为了方便计算,我们用栈来保存当前路径的元素,然后统一在叶子节点处做结算动作

  1. 递归 深度遍历,优先选择左孩子
  2. 当碰到叶子节点时,根据栈中的元素计算当前路径对应的数字
  3. 返回结果即可

二、实现

实现代码

实现代码与思路中保持一致,需要注意的是:需要在递归前先将根节点加入到路径中

public int sumNumbers(TreeNode root) {
    Stack<Integer> stack = new Stack<>();
    stack.push(root.val);
    return dfs(root, stack);
}

public int dfs(TreeNode root, Stack<Integer> currentPath){
    int ret = 0;
    if (root.left == null && root.right == null){
        for (Integer i : currentPath){
            ret = ret*10 + i;
        }
        // 结算
        return ret;
    }
    if (root.left != null){
        currentPath.push(root.left.val);
        ret += dfs(root.left, currentPath);
        currentPath.pop();
    }
    if (root.right != null){
        currentPath.push(root.right.val);
        ret += dfs(root.right, currentPath);
        currentPath.pop();
    }
    return ret;
}

测试代码

public static void main(String[] args) {
    TreeNode treeNode = new TreeNode(1, new TreeNode(2), new TreeNode(3));
    TreeNode treeNode1 = new TreeNode(4, new TreeNode(9, new TreeNode(5), new TreeNode(1)), new TreeNode(0));
    int ret = new Number129().sumNumbers(treeNode1);
    System.out.println(ret);
}

结果

image.png

三、总结

后面我去看了一下官方的题解,发现其实也可以不用栈来存储当前的路径。递归中使用 preSum 标识之前路径的值即可。这样代码更简洁,也更容易让人读懂。

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~