问题:给定一颗二叉树,节点的值只能为0~9中的一个,每一个从根节点到叶子节点的路径代表一个数,比如,有一个从根节点到叶子节点的路径是 1->2->3,则这个路径代表数字是123。求出从根节点到所有叶子节点的路径所代表数字的和是多少。
再比如,有如下二叉树:
1 / \ 2 3问题的答案=12 + 13 = 25
二叉树的结构如下:
//Definition for binary tree
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
方法一:使用递归。可以考虑深度优先遍历,程序需要保存一个整形变量sum,表示在这条路径上已经遍历得到的数字;然后遍历下一个节点node,如果node为空,返回sum即可,如果node是叶子节点,返回sum*10 + node.val即可,否则,对左孩子和右孩子递归调用此方法。
public int sumNumbers(TreeNode root) {
return sum(root, 0);
}
public int sum(TreeNode n, int s){
if (n == null) return 0;
if (n.right == null && n.left == null) return s*10 + n.val;
return sum(n.left, s*10 + n.val) + sum(n.right, s*10 + n.val);
}
方法二:使用非递归。设置两个队列,nodequeue用于存储节点,对于nodequeue中的第i个元素nodei,valqueue中的第i个元素存储从根节点到nodei节点的路径所组成的数字,经过这样的对应关系,我们可以遍历nodequeue队列,当遍历的第i个元素nodei的左孩子不为零时,将左孩子放入nodequeue,将valqueue的第i个元素的值乘以10再加上左孩子的值,放入valqueue队列,对右孩子做同样的操作。当遍历的节点nodei是叶子节点时,说明从根节点到nodei节点的数字已经计算完成了,当所有的从根节点到叶子节点的数字都计算完成,即nodequeue队列为空时,将这些数字相加就得到了结果。
public int sumNumbers(TreeNode root) {
if(root == null)
return 0;
Queue<TreeNode> nodequeue = new LinkedList<TreeNode>();
Queue<Integer> valqueue = new LinkedList<Integer>();
nodequeue.offer(root);
valqueue.offer(root.val);
int sum = 0;
while(!nodequeue.isEmpty()){
TreeNode node = nodequeue.poll();
Integer val = valqueue.poll();
if(node.left != null){
nodequeue.offer(node.left);
valqueue.offer((Integer)(val*10 + node.left.val));
}
if(node.right != null){
nodequeue.offer(node.right);
valqueue.offer((Integer)(val*10 + node.right.val));
}
if(node.left == null && node.right == null){
sum += val;
}
}
return sum;
}