力扣【二叉树专题】1022. 从根到叶的二进制数之和

132 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 11 天,点击查看活动详情

题目链接

1022. 从根到叶的二进制数之和 - 力扣(LeetCode)

题目描述

给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。

例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。 对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。

返回这些数字之和。题目数据保证答案是一个 32 位 整数。

测试用例

示例 1:

image.png

输入:root = [1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22

限制

  • 树中节点的数目在范围 [1,104][1, 10^4] 内
  • Node.val 仅为 0 或 1

题目分析

已知有一颗树,他的全部节点的值仅为 0 或 1,需要我们遍历拿到他的全部的、从根到叶子节点的路径,然后将路径上对应的节点的值顺序拼接成类似于 1000 的二进制形式的字符串;我们需要遍历拿到全部的路径对应的二进制字符串,并转化为十进制并求和返回,题目保证最后的返回值不会超过 2322^{32}

我们使用一个栈来辅助记录下遍历时的节点的路径,当 当前节点 为叶子节点时(即左右子节点都为null),我们将栈中的节点值都记录下来;当我们遍历完此节点,返回到上一级时,需要将当前节点的值从栈中弹出

最后对拿到的所有路径,进行进制转化并求和,即可

代码实现

完整的代码实现如下

var sumRootToLeaf = function(root) {
    let arr = [];
    let strs = [];
    trave(root);
    return strs.map(n => parseInt(n, 2)).reduce((a, b) => a + b, 0);

    function trave(node) {
        if (node == null) return;
        arr.push(node.val);
        trave(node.left);
        trave(node.right);
        if (node.left == null && node.right == null) { // 叶子节点
            strs.push(arr.join(''));
        }
        arr.pop();
    }
};

image.png

优化

复盘代码,发现没有必要再额外使用数组去记录下遍历的路径再求和,优化的思路就是使用 sum 替换掉 strs,在树的遍历过程中,直接将路径转为十进制,并将和累加到 sum 即可

image.png