Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.
这题是昨天早上起来趁着电脑没电之前做的,典型的dfs;我尝试自己写了一下,调试了两遍还真AC了,有点开心,感觉自己进步还是有的。
我当时思路是这样的:
从root开始dfs,找到left结点的时候就把值保存到一个list里,最后把list里的元素加起来。Time complexity: O(n),Space: O(n)。
写起来就很直观,因为是void类型的dfs函数,所以只需要考虑什么时候terminate就可以。curNum是基本类型,每次创建新的内存地址来保存,不需要恢复现场。
一开始我算出来的数都是答案的双倍,因为当时我只判断了root == null然后add,导致每个叶子结点都要add两次。后来增加了对叶子结点的单独处理。另外,这题是必须要有root == null这种判断的,否则对于只有一个child的node就会出现空指针错误。
代码写得有点长:
public int sumNumbers(TreeNode root) {
if (root == null) return 0;
List<Integer> res = new ArrayList<>();
dfs(root, 0, res);
int sum = 0;
for (Integer i : res) {
sum += i;
}
return sum;
}
private void dfs(TreeNode root, int curNum, List<Integer> res) {
if (root == null) {
return;
}
if (root!=null && root.left == null && root.right == null){
curNum = curNum * 10 + root.val;
res.add(curNum);
return;
}
curNum = curNum * 10 + root.val;
dfs(root.left, curNum, res);
dfs(root.right, curNum, res);
}
那这个代码就很长,而且用到了O(n)的空间。我去看了leetcode solutions里的方法,我感觉那边的高票方法一般都还是比较优秀的写法,因为是大家投票出来的,所以一般很简洁,当然也有少数是比较tricky的做法。
高票的代码是这样的:
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);
}
我粗略看了一眼,然后自己敲了一遍:
private int dfs2(TreeNode root , int sum ){
if (root == null )return 0 ;
if (root.left == null && root.right == null) return sum * 10 + root.val ;
sum = sum * 10 + root.val ;
return dfs2(root.left , sum) + dfs2(root.right , sum);
}
感受是要自己在脑子里想一个简单的test case去跑一跑,比如
1
/
2 3
这种,跑一跑看return的会不会是25。
我一开始觉得似乎
if (root.left == null && root.right == null) return sum * 10 + root.val ;
这一句不需要了呀,因为执行的内容跟后面一行一样嘛。但是跑出来发现sum是0,这是因为含有返回值的dfs函数,最后return的一定是终止条件里返回的值呀,如果只有if (root == null )return 0 ;
这一句,当然返回的都是0了。
这题还可以这么写:
public int sumNumbers(TreeNode root) {
return sumNodes(root, 0);
}
private int sumNodes(TreeNode root, int currentSum) {
if (root == null) return 0;
currentSum = currentSum * 10 + root.val;
if (root.left == null && root.right == null) return currentSum;
int leftSum = sumNodes(root.left, currentSum);
int rightSum = sumNodes(root.right, currentSum);
return leftSum + rightSum;
}
Practice makes perfect.
You are the sum of all your training.
新的一周开始了~
24/04/2017