持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 11 天,点击查看活动详情
题目链接
1022. 从根到叶的二进制数之和 - 力扣(LeetCode)
题目描述
给出一棵二叉树,其上每个结点的值都是 0 或 1 。每一条从根到叶的路径都代表一个从最高有效位开始的二进制数。
例如,如果路径为 0 -> 1 -> 1 -> 0 -> 1,那么它表示二进制数 01101,也就是 13 。
对树上的每一片叶子,我们都要找出从根到该叶子的路径所表示的数字。
返回这些数字之和。题目数据保证答案是一个 32 位 整数。
测试用例
示例 1:
输入:root = [1,0,1,0,1,0,1]
输出:22
解释:(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22
限制
- 树中节点的数目在范围 内
Node.val仅为0或1
题目分析
已知有一颗树,他的全部节点的值仅为 0 或 1,需要我们遍历拿到他的全部的、从根到叶子节点的路径,然后将路径上对应的节点的值顺序拼接成类似于 1000 的二进制形式的字符串;我们需要遍历拿到全部的路径对应的二进制字符串,并转化为十进制并求和返回,题目保证最后的返回值不会超过
我们使用一个栈来辅助记录下遍历时的节点的路径,当 当前节点 为叶子节点时(即左右子节点都为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();
}
};
优化
复盘代码,发现没有必要再额外使用数组去记录下遍历的路径再求和,优化的思路就是使用 sum 替换掉 strs,在树的遍历过程中,直接将路径转为十进制,并将和累加到 sum 即可