Remove All Nodes Which Don't Lie in Any Path With Sum>=k using C++

C++Server Side ProgrammingProgramming

In this problem, we have a binary tree with a path from the root node to the leaf node that is completely defined. The sum of all nodes from a root node to a leaf node must be greater than or equal to k. So we need to remove all nodes in the paths whose sum is less than k. An important thing to remember here is that a node may be a part of many paths, so only remove such nodes if all the paths have sum < k.

From the root node to the leaf node, we can calculate the sum. When the recursive call completes for a node and control returns, we can check if the sum is < k for both left and right paths. If the sum is less than k for both the left and right paths, we need to remove this node.

Let's suppose we have 150 K and a tree like this −

      10
      / \
     20 30
    / \  / \
   5 35 40 45
   / \ / \
  50 55 60 65
  / \    / /
  70 80 90 100

If we see that the path root->left->left has a sum of 10 + 20 + 5, which is 25, less than 150, we need to prune it and remove 5. After this, let's evaluate 10->30->40. It's less than 150, so remove 40. Now we see another path 10->20->35->50 and the total sum 115 which is less than 150, so we remove 50. Now we have left paths are

10->20->35->55->70 ;
10->20->35->55->80 ;
10->30->45->60->90 ;
10->30->45->65->100 ;

The sum of all paths is greater than 150, so we don't need to prune anymore.

Example

#include <iostream>
using namespace std;
class Node {
   public:
   int value;
   Node *left, *right;
   Node(int value) {
      this->value = value;
      left = right = NULL;
   }
};
Node* removeNodesWithPathSumLessThanK(Node* root, int k, int& sum) {
   if(root == NULL) return NULL;
   int leftSum, rightSum;
   leftSum = rightSum = sum + root->value;
   root->left = removeNodesWithPathSumLessThanK(root->left, k, leftSum);
   root->right = removeNodesWithPathSumLessThanK(root->right, k, rightSum);
   sum = max(leftSum, rightSum);
   if(sum < k) {
      free(root);
      root = NULL;
   }
   return root;
}
void printInorderTree(Node* root) {
   if(root) {
      printInorderTree(root->left);
      cout << root->value << " ";
      printInorderTree(root->right);
   }
}
int main() {
   int k = 150;
   Node* root = new Node(10);
   root->left = new Node(20);
   root->right = new Node(30);
   root->left->left = new Node(5);
   root->left->right = new Node(35);
   root->right->left = new Node(40);
   root->right->right = new Node(45);
   root->left->right->left = new Node(50);
   root->left->right->right = new Node(55);
   root->right->right->left = new Node(60);
   root->right->right->right = new Node(65);
   root->left->right->right->left = new Node(70);
   root->left->right->right->right = new Node(80);
   root->right->right->left->left = new Node(90);
   root->right->right->right->left = new Node(100);
   int sum = 0;
   cout << "Inorder tree before: ";
   printInorderTree(root);
   root = removeNodesWithPathSumLessThanK(root, k, sum);
   cout << "
Inorder tree after: ";    printInorderTree(root);    return 0; }

Output

Inorder tree before: 5 20 50 35 70 55 80 10 40 30 90 60 45 100 65
Inorder tree after: 20 35 70 55 80 10 30 90 60 45 100 65

Tree after we pruned it completely −

         10
         / \
      20 30
      \   \
      35 45
       \ / \
    55  60 65
    / \  /  /
  70 80 90 100

Conclusion

As we can see that after the initial observation, we can apply the DFS and remove nodes as our recursive function returns from each call by computing the sum at that node. Overall a simple observational and methodological problem.

raja
Updated on 18-May-2022 11:48:55

Advertisements