Sum Root Leaf Number

// https://leetcode.com/problems/sum-root-to-leaf-numbers/

// You are given the root of a binary tree containing digits from 0 to 9 only.
// Each root - to - leaf path in the tree represents a number.
// For example, the root - to - leaf path 1 -> 2 -> 3 represents the number 123.
// Return the total sum of all root - to - leaf numbers.
// Test cases are generated so that the answer will fit in a 32 - bit integer.
// A leaf node is a node with no children.

//      2
//    /  \
//   3   4
//  / \
// 1   5

// 231+235+24

#include <vector>
#include <iostream>
#include <stack>

using namespace std;

class TreeNode {
public:
    TreeNode* left;
    TreeNode* right;
    int val;
    TreeNode(int v) : val(v), left(nullptr), right(nullptr) {} 
};

// Iterative, stack or queue.
// Time: O(n), Space: O(H)
int sumNumbersIterative(TreeNode* root) {
    if (!root) {
        return 0;
    }

    stack<pair<TreeNode*, int>> st;
    st.push({root, root->val});

    int res = 0;
    while (!st.empty()) {
        auto curr = st.top();
        st.pop();

        TreeNode* node = curr.first;

        int val = curr.second;
        if (!node->left && !node->right) {
            res += val;
        }
        if (node->left) {
            st.push({node->left, val*10 + node->left->val});
        }
        
        if (node->right) {
            st.push({node->right, val*10 + node->right->val});
        }
    }

    return res;
}

// Morris
/*
The idea of Morris algorithm is to set temporary link between the node and its predecessor.
predecessor.right = root.
If there is no link? set it and go to the left subtree.
If there is a link? break it and go to the right subtree.
*/

// Time: O(N), Space: O(1)
int sumNumbersMorris(TreeNode* root) {
    int rootToLeaf = 0, currNumber = 0;
    TreeNode* predecessor;

    while (root) {
        if (root->left) {
            // Finding the predecessor
            predecessor = root->left;
            int steps = 1;
            while (predecessor->right && predecessor->right != root) {
                predecessor = predecessor->right;
                ++steps;
            }

            // Making a temporary link and moving to the left subtree
            if (!predecessor->right) {
                currNumber = currNumber * 10 + root->val;
                predecessor->right = root;
                root = root->left;
            }
            // Breaking the temporary link and moving to the right subtree
            else {
                // If you're on a leaf, update the sum
                if (!predecessor->left) {
                    rootToLeaf += currNumber;
                }
                // Backtracking the current number
                for (int i = 0; i < steps; ++i) {
                    currNumber /= 10;
                }
                predecessor->right = nullptr;
                root = root->right;
            }
        }
        // If there is no left child, just go right
        else {
            currNumber = currNumber * 10 + root->val;
            // If you're on a leaf, update the sum
            if (!root->right) {
                rootToLeaf += currNumber;
            }
            root = root->right;
        }
    }

    return rootToLeaf;
}

// TODO: pre-order traversal, in-order traversal, post-order traversal.

// Time: O(n), Space: O(H)
void helper(TreeNode* curr, int& res, int sum) {
    if (!curr) {
        return;
    }

    sum += curr->val;
    if (!curr->left && !curr->right) {
        res += sum;
        return;
    }

    helper(curr->left, res, sum*10);
    helper(curr->right, res, sum*10);
}

int sumNumbers(TreeNode* root) {
    int res = 0;
    helper(root, res, 0);
    return res;
}

int main() {
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    cout << sumNumbers(root) << endl;
    cout << sumNumbersIterative(root) << endl;
    cout << sumNumbersMorris(root) << endl;


    //      2
    //    /  \
    //   3   4
    //  / \
    // 1   5

    // 231+235+24
    TreeNode* root2 = new TreeNode(2);
    root2->left = new TreeNode(3);
    root2->right = new TreeNode(4);
    root2->left->left = new TreeNode(1);
    root2->left->right = new TreeNode(5);
    cout << sumNumbers(root2) << endl;
    cout << sumNumbersIterative(root2) << endl;
    cout << sumNumbersMorris(root2) << endl;

//     [5, 3, 2, 7, 0, 6, null, null, null, 0] , 6363
//      5
//     / \
//    3   2
//   / \  /
//  7  0  6
//     \
//      0
    return 0;
}```

Last updated