Open In App

Check if removing an edge can divide a Binary Tree in two halves

Last Updated : 26 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a Binary Tree, the task is to find if there exists an edge whose removal creates two trees of equal size.

Examples:  

Input:

check-if-removing-an-edge-can-divide-a-binary-tree-in-two-halvesb

Output : True
Explanation: Removing edge 5-6 creates two trees of equal size.

Input:

check-if-removing-an-edge-can-divide-a-binary-tree-in-two-halvesa

Output : False
Explanation: There is no edge whose removal creates two trees of equal size.

[Naive Approach] Recursive Method - O(n^2) Time and O(h) Space

The idea is to count the number of nodes in the tree. Let count of all nodes be n. Traverse the tree again and for each node, find size of subtree rooted with this node. Let cnt be the size of subtree size. If n-cnt is equal to cnt, then return true. Otherwise recursively check for left and right subtree.

Below is the implementation of the above approach:

C++
// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include<bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;
    Node(int x) {
        data = x;
        left = nullptr;
        right = nullptr;
    }
};

// To calculate size of tree with given root
int countNodes(Node* root) {
    if (root==nullptr)
        return 0;
    return countNodes(root->left) + countNodes(root->right) + 1;
}

// This function returns true if there is an edge
// whose removal can divide the tree in two halves
// n is size of tree
bool checkRec(Node* root, int n) {
    
    // Base case
    if (root == nullptr)
       return false;
       
    // find the size of current subtree
    int cnt = countNodes(root);

    // If unlinking the current subtree from
    // main tree creates two trees of same size,
    // return true.
    if (cnt == n-cnt)
        return true;

    // Check for rest of the nodes
    return checkRec(root->left, n) ||
           checkRec(root->right, n);
}

// This function mainly uses checkRec()
bool check(Node *root) {
    
    // Count total nodes in given tree
    int n = countNodes(root);
    
    // Now recursively check all nodes
    return checkRec(root, n);
}

int main() {
    
    // Binary tree 
    //     5
    //   / \
    //   1   6
    //  /   / \
    // 3   7   4
    Node* root = new Node(5);
    root->left = new Node(1);
    root->right = new Node(6);
    root->left->left = new Node(3);
    root->right->left = new Node(7);
    root->right->right = new Node(4);

    if (check(root)) {
        cout << "True" << endl;
    } else {
        cout << "False" << endl;
    }

    return 0;
}
C
// C program to check if there exist an edge whose
// removal creates two trees of same size
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};

// To calculate size of tree with given root
int countNodes(struct Node* root) {
    if (root == NULL)
        return 0;
    return countNodes(root->left) + countNodes(root->right) + 1;
}

// This function returns true if there is an edge
// whose removal can divide the tree in two halves
// n is size of tree
int checkRec(struct Node* root, int n) {

    // Base case
    if (root == NULL)
        return 0;

    // find the size of current subtree
    int cnt = countNodes(root);

    // If unlinking the current subtree from
    // main tree creates two trees of same size,
    // return true.
    if (cnt == n - cnt)
        return 1;

    // Check for rest of the nodes
    return checkRec(root->left, n) 
      		|| checkRec(root->right, n);
}

// This function mainly uses checkRec()
int check(struct Node* root) {

    // Count total nodes in given tree
    int n = countNodes(root);

    // Now recursively check all nodes
    return checkRec(root, n);
}

struct Node* createNode(int x) {
    struct Node* newNode = 
    	(struct Node*)malloc(sizeof(struct Node));
    newNode->data = x;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

int main() {

    // Binary tree 
    //     5
    //   / \
    //   1   6
    //  /   / \
    // 3   7   4
    struct Node* root = createNode(5);
    root->left = createNode(1);
    root->right = createNode(6);
    root->left->left = createNode(3);
    root->right->left = createNode(7);
    root->right->right = createNode(4);

    if (check(root)) {
        printf("True\n");
    } else {
        printf("False\n");
    }

    return 0;
}
Java
// Java program to check if there exist an edge whose
// removal creates two trees of same size

import java.util.ArrayList;

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // To calculate size of tree with given root
    static int countNodes(Node root) {
        if (root == null)
            return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }

    // This function returns true if there is an edge
    // whose removal can divide the tree in two halves
    static boolean checkRec(Node root, int n) {

        // Base case
        if (root == null)
            return false;

        // find the size of current subtree
        int cnt = countNodes(root);

        // If unlinking the current subtree from
        // main tree creates two trees of same size,
        // return true.
        if (cnt == n - cnt)
            return true;

        // Check for rest of the nodes
        return checkRec(root.left, n) 
          		|| checkRec(root.right, n);
    }

    // This function mainly uses checkRec()
    static boolean check(Node root) {

        // Count total nodes in given tree
        int n = countNodes(root);

        // Now recursively check all nodes
        return checkRec(root, n);
    }

    public static void main(String[] args) {

        // Binary tree 
        //     5
        //   / \
        //   1   6
        //  /   / \
        // 3   7   4
        Node root = new Node(5);
        root.left = new Node(1);
        root.right = new Node(6);
        root.left.left = new Node(3);
        root.right.left = new Node(7);
        root.right.right = new Node(4);

        if (check(root)) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
}
Python
# Python program to check if there exist an edge whose
# removal creates two trees of same size

class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

# To calculate size of tree with given root
def countNodes(root):
    if root is None:
        return 0
    return countNodes(root.left) \
  			+ countNodes(root.right) + 1

# This function returns true if there is an edge
# whose removal can divide the tree in two halves
def checkRec(root, n):

    # Base case
    if root is None:
        return False

    # find the size of current subtree
    cnt = countNodes(root)

    # If unlinking the current subtree from
    # main tree creates two trees of same size,
    # return true.
    if cnt == n - cnt:
        return True

    # Check for rest of the nodes
    return checkRec(root.left, n) or checkRec(root.right, n)

# This function mainly uses checkRec()
def check(root):

    # Count total nodes in given tree
    n = countNodes(root)

    # Now recursively check all nodes
    return checkRec(root, n)

if __name__ == "__main__":

    # Binary tree 
    #     5
    #   / \
    #   1   6
    #  /   / \
    # 3   7   4
    root = Node(5)
    root.left = Node(1)
    root.right = Node(6)
    root.left.left = Node(3)
    root.right.left = Node(7)
    root.right.right = Node(4)

    if check(root):
        print("True")
    else:
        print("False")
C#
// C# program to check if there exist an edge whose
// removal creates two trees of same size

using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // To calculate size of tree with given root
    static int countNodes(Node root) {
        if (root == null)
            return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }

    // This function returns true if there is an edge
    // whose removal can divide the tree in two halves
    static bool checkRec(Node root, int n) {

        // Base case
        if (root == null)
            return false;

        // find the size of current subtree
        int cnt = countNodes(root);

        // If unlinking the current subtree from
        // main tree creates two trees of same size,
        // return true.
        if (cnt == n - cnt)
            return true;

        // Check for rest of the nodes
        return checkRec(root.left, n) 
          		|| checkRec(root.right, n);
    }

    // This function mainly uses checkRec()
    static bool check(Node root) {

        // Count total nodes in given tree
        int n = countNodes(root);

        // Now recursively check all nodes
        return checkRec(root, n);
    }

    static void Main() {

        // Binary tree 
        //     5
        //   / \
        //   1   6
        //  /   / \
        // 3   7   4
        Node root = new Node(5);
        root.left = new Node(1);
        root.right = new Node(6);
        root.left.left = new Node(3);
        root.right.left = new Node(7);
        root.right.right = new Node(4);

        if (check(root)) {
            Console.WriteLine("True");
        } else {
            Console.WriteLine("False");
        }
    }
}
JavaScript
// JavaScript program to check if there exist an edge whose
// removal creates two trees of same size

class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// To calculate size of tree with given root
function countNodes(root) {
    if (root === null) return 0;
    return countNodes(root.left) + 
    countNodes(root.right) + 1;
}

// This function returns true if there is an edge
// whose removal can divide the tree in two halves
function checkRec(root, n) {

    // Base case
    if (root === null) return false;

    // find the size of current subtree
    const cnt = countNodes(root);

    // If unlinking the current subtree from
    // main tree creates two trees of same size,
    // return true.
    if (cnt === n - cnt) return true;

    // Check for rest of the nodes
    return checkRec(root.left, n) || 
    checkRec(root.right, n);
}

// This function mainly uses checkRec()
function check(root) {

    // Count total nodes in given tree
    const n = countNodes(root);

    // Now recursively check all nodes
    return checkRec(root, n);
}

// Binary tree 
//     5
//   / \
//   1   6
//  /   / \
// 3   7   4
const root = new Node(5);
root.left = new Node(1);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.left = new Node(7);
root.right.right = new Node(4);

if (check(root)) {
    console.log("True");
} else {
    console.log("False");
}

Output
True

[Expected Approach] Bottom-Up Manner - O(n) Time and O(h) Space

The idea is to traverse tree in bottom up manner and while traversing, for each node, find the size of the subtree and check if the current node follows the required property.

Below is the implementation of above approach:

C++
// C++ program to check if there exist an edge whose
// removal creates two trees of same size
#include<bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;
    Node(int x) {
        data = x;
        left = nullptr;
        right = nullptr;
    }
};

// To calculate size of tree with given root
int countNodes(Node* root) {
    if (root==nullptr)
        return 0;
    return countNodes(root->left) + 
      countNodes(root->right) + 1;
}

// This function returns size of tree rooted with given
// root. It also set "res" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
int checkRec(Node* root, int n, bool &ans) {
    
    // Base case
    if (root == nullptr)
       return false;
       
    // find the size of current subtree
    int cnt = checkRec(root->left, n, ans) + 
    checkRec(root->right, n, ans) + 1;

    // If unlinking the current subtree from
    // main tree creates two trees of same size,
    // return true.
    if (cnt == n-cnt)
        ans = true;

    // return the size of current
  	// subtree.
    return cnt;
}

// This function mainly uses checkRec()
bool check(Node *root) {
    
    // Count total nodes in given tree
    int n = countNodes(root);
    
    bool ans = false;
    
    // Now recursively check all nodes
    checkRec(root, n, ans);
    
    return ans;
}

int main() {
    
    // Binary tree 
    //     5
    //   / \
    //   1   6
    //  /   / \
    // 3   7   4
    Node* root = new Node(5);
    root->left = new Node(1);
    root->right = new Node(6);
    root->left->left = new Node(3);
    root->right->left = new Node(7);
    root->right->right = new Node(4);

    if (check(root)) {
        cout << "True" << endl;
    } else {
        cout << "False" << endl;
    }

    return 0;
}
Java
// Java program to check if there exist an edge whose
// removal creates two trees of same size
import java.util.*;

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // To calculate size of tree with given root
    static int countNodes(Node root) {
        if (root == null)
            return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }

    // This function returns size of tree rooted with given
    // root. It also sets "ans" as true if there is an edge
    // whose removal divides tree in two halves.
    // n is size of tree
    static int checkRec(Node root, int n, boolean[] ans) {
        
        // Base case
        if (root == null)
            return 0;

        // find the size of current subtree
        int cnt = checkRec(root.left, n, ans) +
                  checkRec(root.right, n, ans) + 1;

        // If unlinking the current subtree from
        // main tree creates two trees of same size,
        // set ans to true
        if (cnt == n - cnt)
            ans[0] = true;

        // return the size of current subtree
        return cnt;
    }

    // This function mainly uses checkRec()
    static boolean check(Node root) {

        // Count total nodes in given tree
        int n = countNodes(root);

        boolean[] ans = {false};

        // Now recursively check all nodes
        checkRec(root, n, ans);

        return ans[0];
    }

    public static void main(String[] args) {

        // Binary tree 
        //     5
        //   / \
        //   1   6
        //  /   / \
        // 3   7   4
        Node root = new Node(5);
        root.left = new Node(1);
        root.right = new Node(6);
        root.left.left = new Node(3);
        root.right.left = new Node(7);
        root.right.right = new Node(4);

        if (check(root)) {
            System.out.println("True");
        } else {
            System.out.println("False");
        }
    }
}
Python
# Python program to check if there exist an edge whose
# removal creates two trees of same size

class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

# To calculate size of tree with
# given root
def countNodes(root):
    if root is None:
        return 0
    return countNodes(root.left) + countNodes(root.right) + 1

# This function returns size of tree rooted with given
# root. It also sets "ans" as True if there is an edge
# whose removal divides tree in two halves.
# n is size of tree
def checkRec(root, n, ans):
    
    # Base case
    if root is None:
        return 0

    # find the size of current subtree
    cnt = checkRec(root.left, n, ans) + \
          checkRec(root.right, n, ans) + 1

    # If unlinking the current subtree from
    # main tree creates two trees of same size,
    # set ans to True
    if cnt == n - cnt:
        ans[0] = True

    # return the size of current subtree
    return cnt

# This function mainly uses checkRec()
def check(root):
    
    # Count total nodes in given tree
    n = countNodes(root)

    ans = [False]

    # Now recursively check all nodes
    checkRec(root, n, ans)

    return ans[0]

if __name__ == "__main__":

    # Binary tree 
    #     5
    #   / \
    #   1   6
    #  /   / \
    # 3   7   4
    root = Node(5)
    root.left = Node(1)
    root.right = Node(6)
    root.left.left = Node(3)
    root.right.left = Node(7)
    root.right.right = Node(4)

    if check(root):
        print("True")
    else:
        print("False")
C#
// C# program to check if there exist an edge whose
// removal creates two trees of same size
using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {

    // To calculate size of tree with given root
    static int countNodes(Node root) {
        if (root == null)
            return 0;
        return countNodes(root.left) + countNodes(root.right) + 1;
    }

    // This function returns size of tree rooted with given
    // root. It also sets "ans" as true if there is an edge
    // whose removal divides tree in two halves.
    // n is size of tree
    static int checkRec(Node root, int n, ref bool ans) {
        
        // Base case
        if (root == null)
            return 0;

        // find the size of current subtree
        int cnt = checkRec(root.left, n, ref ans) +
                  checkRec(root.right, n, ref ans) + 1;

        // If unlinking the current subtree from
        // main tree creates two trees of same size,
        // set ans to true
        if (cnt == n - cnt)
            ans = true;

        // return the size of current 
     	 // subtree
        return cnt;
    }

    // This function mainly uses checkRec()
    static bool check(Node root) {

        // Count total nodes in given tree
        int n = countNodes(root);

        bool ans = false;

        // Now recursively check all nodes
        checkRec(root, n, ref ans);

        return ans;
    }

    static void Main(string[] args) {

        // Binary tree 
        //     5
        //   / \
        //   1   6
        //  /   / \
        // 3   7   4
        Node root = new Node(5);
        root.left = new Node(1);
        root.right = new Node(6);
        root.left.left = new Node(3);
        root.right.left = new Node(7);
        root.right.right = new Node(4);

        if (check(root)) {
            Console.WriteLine("True");
        } else {
            Console.WriteLine("False");
        }
    }
}
JavaScript
// JavaScript program to check if there exist an edge whose
// removal creates two trees of same size

class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// To calculate size of tree with given root
function countNodes(root) {
    if (root === null)
        return 0;
    return countNodes(root.left) + 
    countNodes(root.right) + 1;
}

// This function returns size of tree rooted with given
// root. It also sets "ans" as true if there is an edge
// whose removal divides tree in two halves.
// n is size of tree
function checkRec(root, n, ans) {

    // Base case
    if (root === null)
        return 0;

    // find the size of current subtree
    let cnt = checkRec(root.left, n, ans) + 
              checkRec(root.right, n, ans) + 1;

    // If unlinking the current subtree from
    // main tree creates two trees of same size,
    // set ans to true
    if (cnt === n - cnt)
        ans.val = true;

    // return the size of current subtree
    return cnt;
}

// This function mainly uses checkRec()
function check(root) {

    // Count total nodes in given tree
    let n = countNodes(root);

    let ans = {val: false};

    // Now recursively check all nodes
    checkRec(root, n, ans);

    return ans.val;
}

// Binary tree 
//     5
//   / \
//   1   6
//  /   / \
// 3   7   4
let root = new Node(5);
root.left = new Node(1);
root.right = new Node(6);
root.left.left = new Node(3);
root.right.left = new Node(7);
root.right.right = new Node(4);

if (check(root)) {
    console.log("True");
} else {
    console.log("False");
}

Output
True

Check if removing an edge can divide a Binary Tree in two halves
Article Tags :
Practice Tags :

Similar Reads