解题思路:
思路一:
使用DFS,然后用一个list(记为curPath)来记录当前路径的所有数值,当访问到根节点时将curPath中的数值转换为一个整型数值,计入到结果(res)中。
提交代码:
class Solution {
public int sumNumbers(TreeNode root) {
if(root==null) return 0;
int[] res=new int[1];res[0]=0;
List<Integer> curPath=new ArrayList<>();
curPath.add(root.val);
findPath(root,curPath,res);
return res[0];
}
private void findPath(TreeNode root,List<Integer> curPath,int[] res) {
if(root.left==null&&root.right==null) {
res[0]+=addVal(curPath);
return;
}
if(root.left!=null) {
curPath.add(root.left.val);
findPath(root.left,curPath,res);
curPath.remove(curPath.size()-1);
}
if(root.right!=null) {
curPath.add(root.right.val);
findPath(root.right,curPath,res);
curPath.remove(curPath.size()-1);
}
}
private int addVal(List<Integer> list) {
int res=0;
for(int i=0;i<list.size();i++)
res+=list.get(i)*Math.pow(10, list.size()-i-1);
return res;
}
}
运行结果:
思路二:
上述代码过于复杂和费时的原因是 我企图遍历到叶节点时就将当前路径的结果加入到最终结果res中 。例如对于这颗树:
我先走到节点5,然后将这条路径中的数值495计入到结果中,然后回到根节点9,再遍历到叶节点1,得到数值491,再计入到最终结果res中。
如果是这种方式,我需要一个list(代码中用curPath表示)来维护当前的路径值,同时需要实时地更新当前的结果——一个int型的变量res。但是一个整型的数值是不能在函数之间传播的,所以我将res设置为一个长度为1的数组,通过修改这个数组的值来达到更新res的目的。
改善的方法是将左右子树的结果传递到父结点,然后加上父结点的值后一层一层上传当前层的节点值,例如对于同样的一颗树:
遍历到叶节点5时,5的左右子树为空,因此将数值5上传给9。同时遍历到叶节点1时,1将数值1上传给9。此时9的左子树数值为5,右子树数值为1,更新为95+91=186后,节点9将自己的数值186上传给父节点4。
这样处理下来就不用额外的list变量来维护当前路径中的数值了,也不用实时更新当前的结果值res。
总之就是将从上到下的计数方式改善为从下到上的计数方式。
提交代码:
class Solution {
public int sumNumbers(TreeNode root) {
return getVal(root,0);
}
private int getVal(TreeNode root,int curVal) {
if(root==null) return 0;
if(root.left==null&&root.right==null) return curVal*10+root.val;
int leftVal=root.left!=null?getVal(root.left,curVal*10+root.val):0;
int rightVal=root.right!=null?getVal(root.right,curVal*10+root.val):0;
return leftVal+rightVal;
}
}
运行结果: