[LeetCode 129] 根节点到叶子节点数字求和(Sum Root to Leaf Numbers)

问题

给定一个节点取值只包含数字0-9的二叉树,每条根节点至叶子节点的路径都可以表示一个数字。

例如,根至叶子路径1->2->3表示数字123。

求所有根至叶子数字的和。

例如,

    1

  /   \

2      3

根至叶子路径1->2表示数字12

根至叶子路径1->3表示数字13

返回值sum=12+13=25

初始思路

要求和就必须把所有路径列出来,所以解决问题的核心就是要遍历所有根到叶子的路径。遍历二叉树容易想到通过递归访问左右子节点直到找到叶子,此时发现一条路径。所以递归结束的条件是当前节点为叶子节点,而一个叶子节点是没有子节点的,所以递归结束条件用代码表示为:root->left == 0 && root->right == 0

一次递归结束时,需要知道路径中都包含了什么值以求出根至叶子数,因此我们需要一个容器记录本次都走过了哪些节点,这里使用一个std::list<int>。在递归访问过程中,每访问到一个节点,我们把当前节点的值放入容器尾部,而函数返回前把该值弹出以表示返回上一个节点。得到了一个路径中所有节点的值后就可以将其转为转为数字了。由于值都是按顺序放入容器的,所以从头到尾对容器中的每一个值执行 和 = 10 * 当前位置的值 + 和 的逻辑就可以算出该数字了。算出一条路径的数字后我们再将其累加到总和即可。

把上面的理论写成代码:

 1 class Solution {
 2 public:
 3     int sumNumbers(TreeNode *root)
 4     {
 5         sum_ = 0;
 6         path_.clear();
 7         
 8         if(root)
 9         {
10             DoSum(root);
11         }
12         
13         
14         return sum_;
15     }
16     
17 private:
18     void DoSum(TreeNode *root)
19     {
20         path_.push_back(root->val);
21         if(root->left == 0 && root->right == 0)
22         {
23             CountOnePath();
24         }
25         else
26         {
27             if(root->left)
28             {
29                 DoSum(root->left);
30             }
31             if(root->right)
32             {
33                 DoSum(root->right);
34             }
35         }
36         
37         path_.pop_back();
38     }
39     
40     void CountOnePath()
41     {
42         int sum = 0;
43         for(auto iter = path_.begin(); iter != path_.end(); ++iter)
44         {
45             sum = 10 * sum + *iter;
46         }
47         
48         sum_ += sum;
49     }
50     
51     int sum_;
52     std::list<int> path_;
53 };

提交后一次性Judge Small和Judge Large通过。看来本题并没有什么机关。

原文地址:https://www.cnblogs.com/shawnhue/p/leetcode_129.html