Number of ways to divide a Binary tree into two halves

Given a binary tree, the task is to count the number of ways to remove a single edge from the tree such that the tree gets divided into two halves with equal sum.

Examples:

Input: 
          1 
        /   \ 
      -1     -1 
               \ 
                1 
Output: 1
Only way to do this will be to remove the edge from the right of the root.
After that we will get 2 sub-trees with sum = 0.
   1 
  /
-1

and 

-1
  \
   1
will be the two sub-trees.

Input:
          1 
        /   \ 
      -1     -1 
               \ 
                -1 
Output: 2

A simple solution will be to remove all the edges of the tree one by one and check if that splits the tree into two halves with the same sum. If it does, we will increase the final answer by 1. This will take O(N2) time in the worst case where “N” is the number of nodes in the tree.

Efficient appraoch:

  1. Create a variable ‘sum’ and store the sum of all the elements of the Binary tree in it. We can find the sum of all the elements of a Binary tree in O(N) time as discussed in this article.
  2. Now we perform the following steps recursively starting from root node:
    • Find the sum of all the elements of its right sub-tree (“R”). If it’s equal to half of the total sum, we increase the count by 1. This is because removing the edge connecting the current node with its right child will divide the tree into two trees with equal sum.
    • Find the sum of all the elements of its left sub-tree (“L”). If it’s equal to half of the total sum, we increase the count by 1.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Node of a binary tree
struct node {
    int data;
    node* left;
    node* right;
    node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
  
// Function to find the sum of
// all the nodes of BST
int findSum(node* curr)
{
    // If current node is
    // null
    if (curr == NULL)
        return 0;
  
    // Else
    return curr->data + findSum(curr->left)
           + findSum(curr->right);
}
  
// Function to recursively check
// if removing any edge divides tree into
// two halves
int checkSum(node* curr, int sum, int& ans)
{
    // Variable to store the
    // sum from left and right
    // child
    int l = 0, r = 0;
  
    // Checking sum from left sub-tree
    // if its not null
    if (curr->left != NULL) {
        l = checkSum(curr->left, sum, ans);
        if (2 * l == sum)
            ans++;
    }
  
    // Checking sum from right sub-tree
    // if its not null
    if (curr->right != NULL) {
        r = checkSum(curr->right, sum, ans);
        if (2 * r == sum)
            ans++;
    }
  
    // Finding the sum of all the elements
    // of current node
    return l + r + curr->data;
}
  
// Function to return the number
// of ways to remove an edge
int cntWays(node* root)
{
    // If root is null
    if (root == NULL)
        return 0;
  
    // To store the final answer
    int ans = 0;
  
    // Sum of all the elements of BST
    int sum = findSum(root);
  
    // If sum is odd then it won't be possible
    // to break it into two halves
    if (sum % 2 == 1)
        return 0;
  
    // Calling the checkSum function
    checkSum(root, sum, ans);
  
    // Returning the final answer
    return ans;
}
  
// Driver code
int main()
{
    node* root = new node(1);
    root->left = new node(-1);
    root->right = new node(-1);
    root->right->right = new node(1);
  
    // Print the count of possible ways
    cout << cntWays(root);
  
    return 0;
}

chevron_right


Output:

1

Time complexity of this approach will be O(N) and space complexity will O(H) where “N” equals number of node in Binary tree and “H” equals height of the Binary Tree.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.