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.
(1)递归的解法:
运行时间超长的代码:有点类似于112,113的path sum,112,113,均是求从根节点到叶子节点的节点元素之和等于某一具体的值得路径,112是判断存不存在这样一条路径,113是判断存不存在这样的路径,并返回出满足条件的多条路径,均采用的是前序遍历的思想,因为前序遍历是优先遍历根节点的,其次是左孩子,再是右孩子。
void sumNumbers(TreeNode* root,int &sum,int temp)
{
temp = temp*10+root->val;
if(root->left == NULL && root->right == NULL)
sum+=temp;
if(root->left!=NULL)
sumNumbers(root->left,sum,temp);
if(root->right!=NULL)
sumNumbers(root->right,sum,temp);
}
int sumNumbers(TreeNode* root) {
if(root == NULL) return 0;
else if(root->left == NULL && root->right == NULL) return root->val;
int sum = 0;
int temp = 0;
sumNumbers(root,sum,temp);
}
在上述代码之后,精华上述代码后,代码如下(运行时间依旧没有提高上去):
int sumNumbers(TreeNode* root,int sum)
{
if(root == NULL) return 0;
sum = sum*10+root->val;
if(root->left == NULL && root->right == NULL)
return sum;
return sumNumbers(root->left,sum)+sumNumbers(root->right,sum);
}
int sumNumbers(TreeNode* root) {
return sumNumbers(root,0);
}
同样的逻辑思路,发现用java实现能节约时间,将运行时间由3ms提升至1ms
public int sumNumbers(TreeNode root) {
if (root == null)
return 0;
return sumR(root, 0);
}
public int sumR(TreeNode root, int x) {
if (root.right == null && root.left == null)
return 10 * x + root.val;
int val = 0;
if (root.left != null)
val += sumR(root.left, 10 * x + root.val);
if (root.right != null)
val += sumR(root.right, 10 * x + root.val);
return val;
}
同样将上述思路扩展到链表上,如果把这个问题扩展一下,在链表中,也有类似问题。如果一个链表是1->2->3->4->5,那么它将表达12345这个数,完美~~
int sumLinkedList(ListNode* node, int sum){
if(node==NULL)
return sum;
sum=sum*10+node->val;
return sumLinkedList(node->next,sum);
}
int sumLinkedList(ListNode* root){
return sumLinkedList(root,0);
}
(2)非递归的方法
代码一:–运行时间比递归的时间还要长,性能要差,非递归的方法注意一次循环只能压入一个节点,因为防止压入多次造成cur = (cur - temp->val) / 10的计算错乱
int sumNumbers(TreeNode* root) {
if(root == NULL)
return 0;
stack<TreeNode*> sta;
sta.push(root);
map<TreeNode*, bool> visited;
visited[root] = true;
int result = 0;
int cur = 0;
cur += root->val;
while(!sta.empty())
{
TreeNode* temp = sta.top();
if(temp->left != NULL && visited[temp->left] == false)
{
sta.push(temp->left);
visited[temp->left] = true;
cur = cur * 10 + temp->left->val;
continue; //一次只能压入一个节点,否则压入多次cur = (cur - temp->val) / 10的计算会错乱
}
if(temp->right != NULL && visited[temp->right] == false)
{
sta.push(temp->right);
visited[temp->right] = true;
cur = cur * 10 + temp->right->val;
continue;
}
if(temp->left == NULL && temp->right == NULL)
result += cur;
sta.pop();
cur = (cur - temp->val) / 10;
}
return result;
}