Given a binary tree and a target sum, find all root-to-leaf paths where each path’s sum equals the given target sum. A leaf is a node with no children.

Sample Input:

Tree:
        5
       / \
      4   8
     /   / \
    11  13  4
   /  \    / \
  7    2  5   1

Target Sum: 22

Expected Output:

[
   [5, 4, 11, 2],
   [5, 8, 4, 5]
]

In this example, there are two root-to-leaf paths with the sum of 22: 5 -> 4 -> 11 -> 2 and 5 -> 8 -> 4 -> 5.

Time and Space Complexity:


The time complexity of the algorithm is O(n^2), where ‘n’ is the number of nodes in the binary tree. In the worst case, we may need to explore all possible paths, and each path can have a maximum length of ‘n’. The space complexity is O(h), where ‘h’ is the height of the binary tree. In the worst case, the recursion stack can grow to the height of the tree.

Now, let’s provide the C++ solution with comments explaining the code:

#include <iostream>
#include <vector>

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

void findPaths(TreeNode* root, int sum, std::vector<int>& currentPath, std::vector<std::vector<int>>& result) {
    // Base case: if the root is null, we can't proceed further
    if (root == nullptr) {
        return;
    }

    // Add the current node to the current path
    currentPath.push_back(root->val);

    // If it's a leaf node and its value equals the remaining sum, we have a valid path
    if (root->left == nullptr && root->right == nullptr && root->val == sum) {
        result.push_back(currentPath);
    }

    // Recursively check the left and right subtrees
    findPaths(root->left, sum - root->val, currentPath, result);
    findPaths(root->right, sum - root->val, currentPath, result);

    // Remove the current node from the current path to backtrack
    currentPath.pop_back();
}

std::vector<std::vector<int>> pathSum(TreeNode* root, int sum) {
    std::vector<std::vector<int>> result;
    std::vector<int> currentPath;

    findPaths(root, sum, currentPath, result);

    return result;
}

int main() {
    // Construct the binary tree for the sample input
    TreeNode* root = new TreeNode(5);
    root->left = new TreeNode(4);
    root->right = new TreeNode(8);
    root->left->left = new TreeNode(11);
    root->right->left = new TreeNode(13);
    root->right->right = new TreeNode(4);
    root->left->left->left = new TreeNode(7);
    root->left->left->right = new TreeNode(2);
    root->right->right->left = new TreeNode(5);
    root->right->right->right = new TreeNode(1);

    int targetSum = 22;

    // Find all root-to-leaf paths with the target sum
    std::vector<std::vector<int>> paths = pathSum(root, targetSum);

    // Print the result
    std::cout << "Root-to-leaf paths with the sum " << targetSum << " are:\n";
    for (const auto& path : paths) {
        for (int num : path) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }

    // Don't forget to free the allocated memory
    // ...

    return 0;
}

The pathSum function finds all root-to-leaf paths with the given target sum. It uses a helper function findPaths to perform a depth-first search (DFS) and track the current path. Whenever a valid path is found (i.e., a leaf node with the correct sum), it adds that path to the result vector.

In the given example, the function will correctly find the two root-to-leaf paths with the sum of 22, and the output will be:

Root-to-leaf paths with the sum 22 are:
5 4 11 2 
5 8 4 5 

As mentioned earlier, the time complexity is O(n^2) due to exploring all possible paths in the worst case, and the space complexity is O(h) due to the recursion stack, where ‘h’ is the height of the binary tree.