129. Sum Root to Leaf Numbers

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 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 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

你可能感兴趣的:(129. Sum Root to Leaf Numbers)