129. Sum Root to Leaf Numbers

1. Description

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.

2. Example

Example 1:
Input: [1,2,3]
Output: 25
Explanation:
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Therefore, sum = 12 + 13 = 25.

Example 2:
Input: [4,9,0,5,1]
Output: 1026
Explanation:
The root-to-leaf path 4->9->5 represents the number 495.
The root-to-leaf path 4->9->1 represents the number 491.
The root-to-leaf path 4->0 represents the number 40.
Therefore, sum = 495 + 491 + 40 = 1026.

3. Note

  • A leaf is a node with no children.

4. Solutions

My Accepted Solution

113. Path Sum II

n is the number of nodes in the tree
Time complexity: O(n)
Space complexity: O(n)

class Solution 
{
public:
    // int sumNumbers(TreeNode* root)
    int sumNumbers(TreeNode *i_root) 
    {
        int result = 0;        
        string pathValues;
        stack<TreeNode *> parentNodes;
        
        for(auto iter = i_root; iter || !parentNodes.empty(); )
        {         
            cout <<pathValues <<endl;
            if(iter) // at this condition, the node is valid, we continually go left
            {       
                pathValues.push_back('0' + iter->val);
                
                if(!iter->left && !iter->right) result += stoi(pathValues);
                
                parentNodes.push(iter);
                iter = iter->left;
            }
            else // at this condition, the node is invalid
            {
                iter = parentNodes.top(); // so we need to get a valid node
                parentNodes.pop();

                // no matter the last node locates at the left subtree or the right subtree
                // we will never go to the left tree, so we cut it
                iter->left = nullptr; 

                // if the iter->right is valid, we could to and check the right subtree
                // but at the same time, we must cut the right subtree, otherwise we will enter a dead loop
                // we go right, and come back to the current node, then we find the right subtree is valid, so we go right again
                // also, we have push the current node into the path, since there may have a valid answer at the right subtree
                if(iter->right)
                {
                    parentNodes.push(iter);
                    iter = iter->right;

                    parentNodes.top()->right = nullptr;
                }
                else 
                {
                    // if the iter->right is invalid, the current node is useless
                    // we just drop it, and hope go back to its parent to continue the process
                    pathValues.pop_back();
                    iter = nullptr;
                }
            }
        }
        
        return result;
    }
};

n is the number of nodes in the tree
Time complexity: O(n)
Space complexity: O(n)

class Solution 
{
private:
    int sumNumbers(TreeNode *i_root, int baseNumber)
    {
        if(!i_root) return 0;
        
        int newBaseNumber = baseNumber * 10 + i_root->val;
        
        if(!i_root->left && !i_root->right) return newBaseNumber;
        
        return sumNumbers(i_root->left, newBaseNumber) + sumNumbers(i_root->right, newBaseNumber);
    }
public:
    // int sumNumbers(TreeNode* root)
    int sumNumbers(TreeNode *i_root) 
    {
        return sumNumbers(i_root, 0);
    }
};
comments powered by Disqus