[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通过。看来本题并没有什么机关。