Given a binary tree consisting of N nodes, the task is to split the binary tree into two subtrees by removing one edge such that the absolute difference of the sum of the subtrees is minimized.
Example:
Input: 1
/ \
2 3
/ \ \
4 5 8
/ \
6 7
Output: 6
Explanation: Split the tree between vertex 3 and 8. Subtrees created have sums 21 and 15Input: 1
/ \
2 3
/ \ / \
4 5 6 7
Output: 4
Explanation: Split the tree between vertex 1 and 3. Subtrees created have sums 16 and 12
Approach: Given problem can be solved by following the steps below:
- Initialize variable minDiff to maximum value of Integer which will store the answer
- Use postorder traversal to store the sum of current node, left subtree and right subtree in the current node
- Use preorder traversal and at every recursive call find the sum of subtrees if the split is between:
- current node and left child node
- current node and right child node
- Update minDiff if at any recursive call the difference of subtrees is less than minDiff
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
struct Node {
Node* left;
Node* right;
int val;
Node( int val)
{
this ->val = val;
this ->left = nullptr;
this ->right = nullptr;
}
}; int postOrder(Node* root)
{ if (root == nullptr)
return 0;
root->val += postOrder(root->left) + postOrder(root->right);
return root->val;
} void preOrder(Node* root, int minDiff[])
{ if (root == nullptr)
return ;
// Absolute difference in subtrees
// if left edge is broken
int leftDiff = abs (root->left->val - (root->val - root->left->val));
// Absolute difference in subtrees
// if right edge is broken
int rightDiff = abs (root->right->val - (root->val - root->right->val));
// Update minDiff if a difference
// lesser than it is found
minDiff[0] = min(minDiff[0], min(leftDiff, rightDiff));
return ;
} // Function to calculate minimum absolute // difference of subtrees after // splitting the tree into two parts int minAbsDiff(Node* root)
{ // Reference variable
// to store the answer
int minDiff[1];
minDiff[0] = INT_MAX;
// Function to store sum of values
// of current node, left subtree and
// right subtree in place of
// current node's value
postOrder(root);
// Function to perform every
// possible split and calculate
// absolute difference of subtrees
preOrder(root, minDiff);
return minDiff[0];
} int main()
{ // Construct the tree
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
// Print the output
cout << minAbsDiff(root);
return 0;
} // This code is contributed by mukesh07. |
// Java implementation for the above approach import java.lang.Math;
import java.io.*;
class GFG {
static class Node {
Node left, right;
int val;
public Node( int val)
{
this .val = val;
this .left = this .right = null ;
}
}
// Function to calculate minimum absolute
// difference of subtrees after
// splitting the tree into two parts
public static int minAbsDiff(Node root)
{
// Reference variable
// to store the answer
int [] minDiff = new int [ 1 ];
minDiff[ 0 ] = Integer.MAX_VALUE;
// Function to store sum of values
// of current node, left subtree and
// right subtree in place of
// current node's value
postOrder(root);
// Function to perform every
// possible split and calculate
// absolute difference of subtrees
preOrder(root, minDiff);
return minDiff[ 0 ];
}
public static int postOrder(Node root)
{
if (root == null )
return 0 ;
root.val += postOrder(root.left)
+ postOrder(root.right);
return root.val;
}
public static void preOrder(Node root,
int [] minDiff)
{
if (root == null )
return ;
// Absolute difference in subtrees
// if left edge is broken
int leftDiff
= Math.abs(root.left.val
- (root.val - root.left.val));
// Absolute difference in subtrees
// if right edge is broken
int rightDiff
= Math.abs(root.right.val
- (root.val - root.right.val));
// Update minDiff if a difference
// lesser than it is found
minDiff[ 0 ]
= Math.min(minDiff[ 0 ],
Math.min(leftDiff, rightDiff));
return ;
}
// Driver code
public static void main(String[] args)
{
// Construct the tree
Node root = new Node( 1 );
root.left = new Node( 2 );
root.right = new Node( 3 );
root.left.left = new Node( 4 );
root.left.right = new Node( 5 );
root.right.left = new Node( 6 );
root.right.right = new Node( 7 );
// Print the output
System.out.println(minAbsDiff(root));
}
} |
# Python3 implementation for the above approach import sys
# Structure of Node class Node:
def __init__( self , val):
self .val = val
self .left = None
self .right = None
# Function to calculate minimum absolute # difference of subtrees after # splitting the tree into two parts def minAbsDiff(root):
# Reference variable
# to store the answer
minDiff = [ 0 ] * ( 1 )
minDiff[ 0 ] = sys.maxsize
# Function to store sum of values
# of current node, left subtree and
# right subtree in place of
# current node's value
postOrder(root)
# Function to perform every
# possible split and calculate
# absolute difference of subtrees
preOrder(root, minDiff)
return minDiff[ 0 ]
def postOrder(root):
if (root = = None ):
return 0
root.val + = postOrder(root.left) + postOrder(root.right)
return root.val
def preOrder(root, minDiff):
if (root = = None ):
return
# Absolute difference in subtrees
# if left edge is broken
leftDiff = abs (root.left.val - (root.val - root.left.val))
# Absolute difference in subtrees
# if right edge is broken
rightDiff = abs (root.right.val - (root.val - root.right.val))
# Update minDiff if a difference
# lesser than it is found
minDiff[ 0 ] = min (minDiff[ 0 ], min (leftDiff, rightDiff))
return
# Construct the tree root = Node( 1 )
root.left = Node( 2 )
root.right = Node( 3 )
root.left.left = Node( 4 )
root.left.right = Node( 5 )
root.right.left = Node( 6 )
root.right.right = Node( 7 )
# Print the output print (minAbsDiff(root))
# This code is contributed by rameshtravel07. |
// C# implementation for the above approach using System;
public class GFG {
class Node {
public Node left, right;
public int val;
}
static Node newNode( int data)
{
Node newNode = new Node();
newNode.val = data;
newNode.left= null ;
newNode.right = null ;
return newNode;
}
// Function to calculate minimum absolute
// difference of subtrees after
// splitting the tree into two parts
static int minAbsDiff(Node root)
{
// Reference variable
// to store the answer
int [] minDiff = new int [1];
minDiff[0] = Int32.MaxValue;
// Function to store sum of values
// of current node, left subtree and
// right subtree in place of
// current node's value
postOrder(root);
// Function to perform every
// possible split and calculate
// absolute difference of subtrees
preOrder(root, minDiff);
return minDiff[0];
}
static int postOrder(Node root)
{
if (root == null )
return 0;
root.val += postOrder(root.left)
+ postOrder(root.right);
return root.val;
}
static void preOrder(Node root,
int [] minDiff)
{
if (root == null )
return ;
// Absolute difference in subtrees
// if left edge is broken
int leftDiff
= Math.Abs(root.left.val
- (root.val - root.left.val));
// Absolute difference in subtrees
// if right edge is broken
int rightDiff
= Math.Abs(root.right.val
- (root.val - root.right.val));
// Update minDiff if a difference
// lesser than it is found
minDiff[0]
= Math.Min(minDiff[0],
Math.Min(leftDiff, rightDiff));
return ;
}
// Driver code
public static void Main()
{
// Construct the tree
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
root.right.left = newNode(6);
root.right.right = newNode(7);
// Print the output
Console.Write(minAbsDiff(root));
}
} // This code is contributed by SURENDRA_GANGWAR. |
<script> // Javascript implementation for the above approach
// Structure of Node
class Node
{
constructor(val) {
this .left = null ;
this .right = null ;
this .val = val;
}
}
// Function to calculate minimum absolute
// difference of subtrees after
// splitting the tree into two parts
function minAbsDiff(root)
{
// Reference variable
// to store the answer
let minDiff = new Array(1);
minDiff[0] = Number.MAX_VALUE;
// Function to store sum of values
// of current node, left subtree and
// right subtree in place of
// current node's value
postOrder(root);
// Function to perform every
// possible split and calculate
// absolute difference of subtrees
preOrder(root, minDiff);
return minDiff[0];
}
function postOrder(root)
{
if (root == null )
return 0;
root.val += postOrder(root.left)
+ postOrder(root.right);
return root.val;
}
function preOrder(root, minDiff)
{
if (root == null )
return ;
// Absolute difference in subtrees
// if left edge is broken
let leftDiff
= Math.abs(root.left.val
- (root.val - root.left.val));
// Absolute difference in subtrees
// if right edge is broken
let rightDiff
= Math.abs(root.right.val
- (root.val - root.right.val));
// Update minDiff if a difference
// lesser than it is found
minDiff[0]
= Math.min(minDiff[0],
Math.min(leftDiff, rightDiff));
return ;
}
// Construct the tree
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
// Print the output
document.write(minAbsDiff(root));
// This code is contributed by decode2207. </script> |
4
Time Complexity: O(N)
Auxiliary Space: O(1)