Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path1->2->3which represents the number123.
Find the total sum of all root-to-leaf numbers.
For example,
1 / \ 2 3
The root-to-leaf path1->2represents the number12.
The root-to-leaf path1->3represents the number13.
Return the sum = 12 + 13 =25.
题目本身看起来很简单的,但是如果对于对属性结构和递归编程不是那么熟的人来说就会遇到很多细节的问题了。后来参考了网上的一些答案,发现基本上都没有详细解析的,也许高手们不屑去分析吧。倒是LeetCode上还是有分析得挺好的,不过也是分析得挺简单的,更没有说他们是如何想到的。
做这道题的时候,我自己遇到的问题:
1. 如何分情况?
2. 如何递归到该点的时候该如何操作?
3. 由跟节点到叶子节点的时候,每进入一层就需要把前面的值*10,如何处理这个值?总值又是如何保存的呢?
问题处理:
1 分情况就是:一 空节点, 二 到了叶子节点 三 一般节点(包括只有左孩子,只有右孩子,两个孩子都有)
2 递归到该点的时候就把这点的值与前面的值乘以10,然后相加
3 需要如何保存前面的值?以参数传递的方式保存,以供下一层使用。总值可以以两种方式保存:参数传递方式,返回函数值方式。
至于怎么想到的?我觉得第一和第二种情况都比较好想,就是第三种情况不太好想了,还是需要多编程,多思考才会想到吧。然后当成一个固定招式记忆下来。
然后就是程序了,参考了LeetCode上的程序,然后写了个我觉得最好理解的贴在这里,顺便带上完整测试程序:
#include<iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
int sumNumbers(TreeNode *root) {
return sumAll(root, 0);
}
int sumAll(TreeNode *root, int sum) {
if (root == nullptr) return 0;//情况1
if (root->left == nullptr && root->right == nullptr)
return sum * 10 + root->val;//情况2。访问节点,把父母及以上层的值乘以10,然后和当前节点值+
else//情况3。把当前节点值和父母及以上层节点值*10,当做参数传递给下一层为下一层节点的:父母及以上层节点值。
return sumAll(root->left, sum * 10 + root->val)
+ sumAll(root->right, sum * 10 + root->val);
}
};
int main()
{
TreeNode root(0);
TreeNode *r;
TreeNode l1(6);
TreeNode l2(2);
TreeNode r1(4);
TreeNode r2(5);
r=&root;
root.right = &r1;
root.right->right = &r2;
root.left = &l1;
root.left->left = &l2;
Solution solu;
cout<<solu.sumNumbers(r)<<endl;
return 0;
}
总结:
算法最恼人的地方就是:经常差那么一点点没有做出来。
以前有人对我说程序写好了就是没有出结果。他们的意思是:Looks like some kind of magic disturbing my program.
但是我觉得:There is no magic. It's logic.只不过就差那么一点点。
很多看起来简单的程序就是差那么一点!逻辑的东西来不得半点偏差。
熟悉了递归回溯和树的遍历,那么本题其实算是很简单的题目。2星级难度。
//2014-2-18 update
int sumNumbers(TreeNode *root)
{
int sum = 0;
sumup(root, sum);
return sum;
}
void sumup(TreeNode *r, int &sum, int path_sum = 0)
{
if (!r) return;
int t = path_sum*10 + r->val;
sumup(r->left, sum, t);
sumup(r->right, sum, t);
if (!r->left && !r->right) sum += t;
}
//2014-2-18 update
int sumNumbers(TreeNode *root)
{
return sumup(root);
}
int sumup(TreeNode *r, int path = 0)
{
if (!r) return 0;
if (!r->left && ! r->right) return 10*path+r->val;
return sumup(r->left, 10*path+r->val)+sumup(r->right, 10*path+r->val);
}