从根到叶的二进制数之和
难度:
标签:
题目描述
给出一棵二叉树,其上每个结点的值都是 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
示例 2:
输入:root = [0] 输出:0
提示:
- 树中的节点数在
[1, 1000]
范围内 Node.val
仅为0
或1
代码结果
运行时间: 23 ms, 内存: 0.0 MB
/*
* 思路:
* 1. 使用Java Stream的方式计算从根到叶子的路径的值。
* 2. 我们需要对每个路径计算其二进制数,并累加这些值。
*/
import java.util.stream.Stream;
import java.util.stream.IntStream;
public class Solution {
public int sumRootToLeaf(TreeNode root) {
return sum(root, 0);
}
private int sum(TreeNode node, int currentSum) {
if (node == null) {
return 0;
}
currentSum = (currentSum << 1) | node.val;
if (node.left == null && node.right == null) {
return currentSum;
}
return Stream.of(node.left, node.right)
.flatMapToInt(n -> IntStream.of(sum(n, currentSum)))
.sum();
}
}
// TreeNode类定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
解释
方法:
该题解采用了迭代的深度优先搜索(DFS)方法来解决问题。首先,如果根节点为空,则直接返回0。对于非空的树,使用一个栈来存储需要遍历的节点及其对应的当前二进制数值。栈的初始化包含根节点和其值。在遍历过程中,每次从栈中弹出一个元素,检查是否为叶子节点(即左右子树都为空)。如果是叶子节点,则将当前的二进制数值加到结果中。如果不是叶子节点,则对其非空的子节点进行处理,将子节点以及对应的更新后的二进制数值(当前值左移一位加上子节点的值,即currVal * 2 + currTree.child.val)压入栈中。这个过程重复直到栈为空,最后返回累加的结果。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么选择使用迭代的深度优先搜索(DFS)而不是递归的DFS方法来解决这个问题?
▷🦆
在处理二进制数累加时,是否有可能出现整数溢出,特别是当树的深度接近或等于32时?
▷🦆
如何确保在从栈中弹出的元素都正确地表示从根到当前节点的路径的二进制数值?
▷🦆
题解中提到,如果节点不是叶子节点则继续处理其子节点。如果当前节点的左或右子节点为null,应如何处理以保持算法的正确性?
▷