力扣【二叉树专题】👊 129. 求根节点到叶节点数字之和

176 阅读2分钟

theme: hydrogen

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 11 天,点击查看活动详情

题目链接

129. 求根节点到叶节点数字之和 - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。 每条从根节点到叶节点的路径都代表一个数字:

例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。 计算从根节点到叶节点生成的 所有数字之和 。

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

测试用例

示例 1:

image.png

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

限制

  • 树中节点的数目在范围 [1, 1000] 内
  • 0 <= Node.val <= 9
  • 树的深度不超过 10

题目分析

题目需要我们得到所有的从根节点到叶子节点的路径,然后将路径上的节点的值,以字符串连接的方式合并到一起,然后再转化为整数;按这种方式处理得到所有的路径对应的值后,然后将他们累加后作为结果返回

很明显,这又是一个深度遍历的题。

定义一个 sum 用于记录累加求和。使用一个数组 arr,在遍历到一个新的节点的时候,将节点的值,存入到 arr 中;当递归完这个节点的左右子节点后,再将 arr 中的最后一个值弹出(即弹出这个节点的对应的值)

在弹出节点的值的这一步操作之前,我们需要检查这个节点是否为叶子节点;当为叶子节点的时候,我们将 arr 中的单个的值以字符串的模式连接再转整数,然后将此数累加至 sum

最后,返回 sum 即可

代码实现

var sumNumbers = function(root) {
    let arr = [],
        sum = 0;
    trave(root);
    return sum;

    function trave(node) {
        if (node == null) return;
        arr.push(node.val);
        trave(node.left);
        trave(node.right);
        if (node.left == null && node.right == null) {
            sum += parseInt(arr.join(''));
        }
        arr.pop();
    }
};

image.png

优化

阅读代码,猜测数组的元素添加、删除操作,以及在叶子节点对数组进行整数转化的操作,影响到了运行的速度

将数组操作替换为 num,添加节点时的操作为 num = num*10 + node.val

最后的移除节点时,将 num10 并保留整数部分

var sumNumbers = function(root) {
    let num = 0;
    sum = 0;
    trave(root);
    return sum;

    function trave(node) {
        if (node == null) return;
        num = num * 10 + node.val;
        trave(node.left);
        trave(node.right);
        if (node.left == null && node.right == null) {
            sum += num;
        }
        num = Math.floor(num/10)
    }
};

优化后,性能接近双百

image.png