SumROotToLeafNumbers [source code]
public class SumROotToLeafNumbers {
static
/******************************************************************************/
class Solution {
public int sumNumbers(TreeNode root) {
if (root == null)
return 0;
Paths res = new Paths (0, 0);
dfs (root, res);
return res.sum;
}
void dfs (TreeNode node, Paths ps) {
ps.path = ps.path * 10 + node.val;
if (node.left == null && node.right == null) {
ps.sum += ps.path;
} else {
if (node.left != null)
dfs (node.left, ps);
if (node.right != null)
dfs (node.right, ps);
}
ps.path /= 10;
}
static class Paths {
int path, sum;
Paths (int p, int ps) {this.path = p; this.sum = ps; }
}
}
/******************************************************************************/
public static void main(String[] args) {
SumROotToLeafNumbers.Solution tester = new SumROotToLeafNumbers.Solution();
}
}
这题首先一个特点就是, 给的例子不够typical, 所以这题上来的一个事情就是先自己举一个例子;
本来还想说跟depth有什么关系, 后来想想, 实际上走一遍DFS就行了, 在leaf的位置collect;
这题好像用returned recursion不如用mutation recursion, 因为比如这个图:
2和3返回上来两个sum, 但是单凭这两个sum, 1还不知道自己当前root level decision应该干什么; 因为1还必须知道左右两个subtree的leaf的数量; 这样就让这个return的过程很复杂; 不如直接用path mutation的方法来在最后leaf的位置收集就行了;
既然用这个思路, 另外一个问题也就出来了, 这题是用leaf位置判断还是pre leaf位置判断?
最后还是比较快的AC了, 速度是1ms (24%), 有过几个小bug;
没有editorial;
https://leetcode.com/problems/sum-root-to-leaf-numbers/discuss/41363/Short-Java-solution.-Recursion.
I use recursive solution to solve the problem.
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);
}
好像returned recursion也没有很复杂的样子;
底下很多人都想到了这个做法, 好像这题的关键就是一个pre Null位置的判断;
The return type provided by problem creator is ‘int’. So I think we shouldn’t consider overflow.
https://leetcode.com/problems/sum-root-to-leaf-numbers/discuss/41400/Can-you-improve-this-algorithm
I prefer the iterative method over recursion. I used 2 queues to do a breadth first traversal. both time and space complexity is O(N):
public class Solution {
public int sumNumbers(TreeNode root) {
int total = 0;
LinkedList<TreeNode> q = new LinkedList<TreeNode>();
LinkedList<Integer> sumq = new LinkedList<Integer>();
if(root !=null){
q.addLast(root);
sumq.addLast(root.val);
}
while(!q.isEmpty()){
TreeNode current = q.removeFirst();
int partialSum = sumq.removeFirst();
if(current.left == null && current.right==null){
total+=partialSum;
}else{
if(current.right !=null){
q.addLast(current.right);
sumq.addLast(partialSum*10+current.right.val);
}
if(current.left !=null){
q.addLast(current.left);
sumq.addLast(partialSum*10+current.left.val);
}
}
}
return total;
}
}
看起来很slick, 实际上代码写的很一般; 并行queue的做法以前是见过的; 因为我们的node本身是一个tree都在被一个queue记录, 所以每一个queue对应的这个path, which also forms a tree, 也需要一个单独的queue来记录;
We can do it without helper function.
class Solution:
# @param root, a tree node
# @return an integer
def sumNumbers(self, root):
if not root:
return 0
if not root.left and not root.right:
return root.val
val = 0
if root.left:
root.left.val += root.val * 10
val += self.sumNumbers(root.left)
root.left.val -= root.val * 10
if root.right:
root.right.val += root.val * 10
val += self.sumNumbers(root.right)
root.right.val -= root.val * 10
return val
这个就比较的hackish了, 看看还是可以的; 实际上就是一个理解DFS本身的顺序, 直接在向下recurse的时候, 把整个path都直接扔到下一个child的val上面;
int sumNumbers(TreeNode *root) {
int sum = 0;
if(root == NULL) return sum;
stack<TreeNode *> array;
stack<int> val;
array.push(root);
val.push(0);
while(!array.empty()){
TreeNode *node = array.top();
int prev = val.top();
array.pop();
val.pop();
while(node->left != NULL){
int cur = prev*10 + node->val;
if(node->right != NULL){
array.push(node->right);
val.push(cur);
}
prev = cur;
node = node->left;
}
int cur = prev*10 + node->val;
if(node->right == NULL){
sum += cur;
}else{
array.push(node->right);
val.push(cur);
}
}
return sum;
}
submission最优解基本就是上面这个做法了;
Problem Description
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.
For example,
1
/ \
2 3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.
Difficulty:Medium
Total Accepted:130.7K
Total Submissions:347.8K
Contributor:LeetCode
Related Topics
treedepth-first search
Similar Questions
Path SumBinary Tree Maximum Path Sum