Given an arbitrary binary tree, your task is to convert it to a binary tree that holds the Children Sum Property, by incrementing the data values of any node.
Note: The structure of tree can't be changed and the node values can't be decremented. Also, there exist multiple possible answers.
Example:
Input: 50
/ \
7 2
/ \ / \
3 5 1 30
Output: 79
/ \
48 31
/ \ / \
43 5 1 30
Explanation: For every node, now its value is equal to the sum of values of its immediate left and right child. One more possible solution is:50
/ \
19 31
/ \ / \
14 5 1 30
Note: We've discussed the naive approach here Convert an arbitrary Binary Tree to a tree that holds Children Sum Property.
In this article, we've discussed an optimized approach to solve the problem, that works in linear time.
Approach:
In the naive approach, we're firstly converting the children nodes and thereafter updating parent node, due to which we required to update the child nodes again. The idea is to convert the children to the maximum possible value so while moving back there will be no parent having more value than the children, so there will be no extra function to again traverse the subtrees from that node.
Step-by-step approach:
- If root is null then return.
- Initialize the variable childSum as 0.
- If root has children, then add their value to childSum.
- If childSum is greater than equal to root->data, then set root->data as childSum.
- Else, if the root's left child is not null, add the difference of root->data and childSum in root->left->data.
- Else, if the root's right child exist, add the difference of root->data and childSum in root->right->data.
- Now modify the root->left and root->right.
- If root is not leaf node, find the sum of root's children, and update the root->data to the sum.
Let us run the algorithm for the given example:
50
/ \
7 2
/ \ / \
3 5 1 30
As sum of children of first node is less than 50 (7 + 2 < 50), update the left node's data (increment 7 to 48).
50
/ \
48 2
/ \ / \
3 5 1 30
Now, sum of children of node with value 48 is less than 48 (3 + 5 < 48), update the left node's data (increment 3 to 43).
50
/ \
48 2
/ \ / \
43 5 1 30
Now, sum of children of node with value 2 is greater than 48 (1 + 30 > 2), update the node's data (increment 2 to 31).
50
/ \
48 31
/ \ / \
43 5 1 30
Now, sum of children of root node is greater than its data i.e. 48 + 31 > 50), update the root's data (increment 50 to 79).
79
/ \
48 31
/ \ / \
43 5 1 30
#include<bits/stdc++.h>
using namespace std;
// Node structure
class Node {
public:
int data;
Node* left;
Node* right;
Node(int data) {
this->data = data;
this->left = nullptr;
this->right = nullptr;
}
};
// Function to modify a tree
// to hold children sum property
void convertTree(Node* root) {
// if root is null, return
if (!root) return;
// find the left and right child sum
int childSum = 0;
if (root->left)
childSum += root->left->data;
if (root->right)
childSum += root->right->data;
// if the root's data is less than
// the sum of its children
if (root->data < childSum) {
root->data = childSum;
}
// if the root's data is greater than
// the sum of its children
else if (root->data > childSum) {
int diff = root->data - childSum;
// if left child is not null
if (root->left)
root->left->data += diff;
// else if right child is not null
else if (root->right)
root->right->data += diff;
}
// modify the left and right subtree
convertTree(root->left);
convertTree(root->right);
// update the root's data to sum
// of child node's data
childSum = 0;
if (root->left)
childSum += root->left->data;
if (root->right)
childSum += root->right->data;
// if root is not leaf node
if(root->left || root->right)
root->data = childSum;
}
// prints the inorder traversal of tree
void printInorder(Node* cur) {
if (cur == nullptr)
return;
printInorder(cur->left);
cout<<cur->data<<" ";
printInorder(cur->right);
}
int main() {
// construct the binary tree
/*
50
/ \
7 2
/ \ / \
3 5 1 30 */
Node *root = new Node(50);
root->left = new Node(7);
root->right = new Node(2);
root->left->left = new Node(3);
root->left->right = new Node(5);
root->right->left = new Node(1);
root->right->right = new Node(30);
printInorder(root);
cout<<endl;
convertTree(root);
printInorder(root);
return 0;
}
// Node structure
class Node {
int data;
Node left;
Node right;
Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function to modify a tree
// to hold children sum property
class GfG {
static void convertTree(Node root) {
// if root is null, return
if (root == null)
return;
// find the left and right child sum
int childSum = 0;
if (root.left != null)
childSum += root.left.data;
if (root.right != null)
childSum += root.right.data;
// if the root's data is less than
// the sum of its children
if (root.data < childSum) {
root.data = childSum;
}
// if the root's data is greater than
// the sum of its children
else if (root.data > childSum) {
int diff = root.data - childSum;
// if left child is not null
if (root.left != null)
root.left.data += diff;
// else if right child is not null
else if (root.right != null)
root.right.data += diff;
}
// modify the left and right subtree
convertTree(root.left);
convertTree(root.right);
// update the root's data to sum
// of child node's data
childSum = 0;
if (root.left != null)
childSum += root.left.data;
if (root.right != null)
childSum += root.right.data;
// if root is not leaf node
if (root.left != null || root.right != null)
root.data = childSum;
}
static void printInorder(Node cur) {
if (cur == null)
return;
printInorder(cur.left);
System.out.print(cur.data + " ");
printInorder(cur.right);
}
public static void main(String[] args) {
Node root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);
printInorder(root);
System.out.println();
convertTree(root);
printInorder(root);
}
}
# Node structure
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to modify a tree
# to hold children sum property
def convertTree(root):
# if root is null, return
if root is None or (root.left is None and root.right is None):
return
# find the left and right child sum
childSum = 0
if root.left is not None:
childSum += root.left.data
if root.right is not None:
childSum += root.right.data
# if the root's data is less than
# the sum of its children
if root.data < childSum:
root.data = root.data + 0 + childSum
# if the root's data is greater than
# the sum of its children
elif root.data > childSum:
diff = root.data - childSum
# if left child is not null
if root.left is not None:
root.left.data = root.left.data + diff
# else if right child is not null
elif root.right is not None:
root.right.data = root.right.data + diff
# modify the left and right subtree
convertTree(root.left)
convertTree(root.right)
# update the root's data to sum
# of child node's data
childSum = 0
if root.left is not None:
childSum += root.left.data
if root.right is not None:
childSum += root.right.data
# if root is not leaf node
if root.left is not None or root.right is not None:
root.data = childSum
# prints the inorder traversal of tree
def printInorder(cur):
if cur is None:
return
printInorder(cur.left)
print(cur.data, end=" ")
printInorder(cur.right)
if __name__ == "__main__":
root = Node(50)
root.left = Node(7)
root.right = Node(2)
root.left.left = Node(3)
root.left.right = Node(5)
root.right.left = Node(1)
root.right.right = Node(30)
printInorder(root)
print()
convertTree(root)
printInorder(root)
// Node structure
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left;
public Node right;
public Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function to modify a tree
// to hold children sum property
class GfG {
static void convertTree(Node root) {
// if root is null, return
if (root == null || (root.left == null && root.right == null))
return;
// find the left and right child sum
int childSum = 0;
if (root.left != null)
childSum += root.left.data;
if (root.right != null)
childSum += root.right.data;
// if the root's data is less than
// the sum of its children
if (root.data < childSum)
root.data = root.data + 0 + childSum;
// else if the root's data is greater than
// the sum of its children
else if (root.data > childSum) {
int diff = root.data - childSum;
// if left child is not null
if (root.left != null)
root.left.data = root.left.data + diff;
// else if right child is not null
else if (root.right != null)
root.right.data = root.right.data + diff;
}
// modify the left and right subtree
convertTree(root.left);
convertTree(root.right);
// update the root's data to sum
// of child node's data
childSum = 0;
if (root.left != null)
childSum += root.left.data;
if (root.right != null)
childSum += root.right.data;
// if root is not leaf node
if (root.left != null || root.right != null)
root.data = childSum;
}
static void printInorder(Node cur) {
if (cur == null)
return;
printInorder(cur.left);
Console.Write(cur.data + " ");
printInorder(cur.right);
}
static void Main() {
Node root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);
printInorder(root);
Console.WriteLine();
convertTree(root);
printInorder(root);
}
}
// Node structure
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function to modify a tree
// to hold children sum property
function convertTree(root) {
// if root is null, return
if (root === null || (root.left === null && root.right === null))
return;
// find the left and right child sum
let childSum = 0;
if (root.left !== null)
childSum += root.left.data;
if (root.right !== null)
childSum += root.right.data;
// if the root's data is less than
// the sum of its children
if (root.data < childSum)
root.data = root.data + 0 + childSum;
// else if the root's data is greater than
// the sum of its children
else if (root.data > childSum) {
let diff = root.data - childSum;
// if left child is not null
if (root.left !== null)
root.left.data = root.left.data + diff;
// else if right child is not null
else if (root.right !== null)
root.right.data = root.right.data + diff;
}
// modify the left and right subtree
convertTree(root.left);
convertTree(root.right);
// update the root's data to sum
// of child node's data
childSum = 0;
if (root.left !== null)
childSum += root.left.data;
if (root.right !== null)
childSum += root.right.data;
// if root is not leaf node
if (root.left !== null || root.right !== null)
root.data = childSum;
}
// prints the inorder traversal of tree
function printInorder(cur) {
if (cur === null)
return;
printInorder(cur.left);
process.stdout.write(cur.data + " ");
printInorder(cur.right);
}
function main() {
let root = new Node(50);
root.left = new Node(7);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(1);
root.right.right = new Node(30);
printInorder(root);
console.log("");
convertTree(root);
printInorder(root);
}
main();
Output
3 7 5 50 1 2 30 43 48 5 79 1 31 30
Time Complexity: O(n), as we are traversing the tree only once.
Auxiliary Space: O(h), where h is the height of tree.