Open In App

Count of leaf nodes required to be removed at each step to empty a given Binary Tree

Last Updated : 24 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given a Binary Tree, the task is to remove the leaf nodes of the Binary Tree during each operation and print the count.

Examples:

Input: 
 

Output: 4 2 1 1 
Explanation: 
In the 1st operation removing the leaf nodes { 1, 3, 4, 6 } from the binary tree. 
In the 2nd operation removing the leaf nodes { 8, 7 } 
In the 3rd operation removing the leaf nodes { 5 } 
In the 4th operation removing the leaf nodes { 2 } 
Therefore, the count of leaf nodes removed in each operation 4 2 1 1.

Input: 
 

Output: 2 1

Naive Approach: The simplest approach to solve this problem to repeatedly traverse the tree for each operation and print the count of leaf nodes currently present in the binary tree and delete all the leaf nodes from the binary tree

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to observe that, a node is not deleted unless both its children have been deleted already. Therefore, it can be determined that on which step a node will be deleted, which will be equal to 1 + maximum path length from that node to any leaf node in the subtree rooted at that node. Follow the steps below to solve this problem:

  • Initialize a Map, say M, to store the leaf nodes at each deletion from the tree.
  • Perform a DFS Traversal on the given Binary Tree following the steps below: 
    • Check if the given node is NULL or not. If found to be true, then return 0.
    • Otherwise, recursively call for left and right nodes and store the values returned from it.
    • Find the maximum height, say maxHeight, when each node will be a leaf node as (1 + maximum of the values returned by the left and right recursive calls) in the above steps for each node.
    • Insert the current node in the Map M at key maxHeight.
  • After completing the above steps, print the count of leaf nodes stored in the Map after each deletion.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Structure of a
// Binary Tree Node
struct Node {
    int data;
    Node *left, *right;
};
 
// Function to allocate
// a new tree node
Node* newNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
 
    return node;
}
 
// Function to find the maximum height
// from leaf in the subtree rooted at
// current node and add that to hashmap
int maxHeightToLeafUTIL(
    Node* curr, map<int, vector<int> >& mp)
{
    if (curr == NULL) {
        return 0;
    }
 
    // Max height to leaf in left subtree
    int leftLeaf
        = maxHeightToLeafUTIL(curr->left, mp);
 
    // Max height to leaf in right subtree
    int rightLeaf
        = maxHeightToLeafUTIL(curr->right, mp);
 
    // Max height to leaf in current subtree
    int maxHeightSubtree
        = 1 + max(leftLeaf, rightLeaf);
 
    // Adding current node to the Map
    mp[maxHeightSubtree].push_back(
        curr->data);
 
    return maxHeightSubtree;
}
 
// Function to find the count of leaf nodes
// by repeatedly removing the leaf nodes
void printAndDelete(Node* root)
{
 
    // Stores the leaf deletion with
    // each iteration
    map<int, vector<int> > mp;
 
    // Function Call to find the order
    // of deletion of nodes
    maxHeightToLeafUTIL(root, mp);
 
    // Printing the map values
    for (auto step : mp) {
 
        cout << mp[step.first].size() << " ";
    }
}
 
// Driver code
int main()
{
    // Given Binary Tree
    Node* root = newNode(2);
    root->right = newNode(7);
    root->right->right = newNode(6);
    root->left = newNode(5);
    root->left->left = newNode(1);
    root->left->right = newNode(8);
    root->left->right->left = newNode(3);
    root->left->right->right = newNode(4);
 
    /*
    Input :
         2
       /   \
      5     7
     / \     \
    1   8     6
       / \
      3   4
*/
 
    // Function Call
    printAndDelete(root);
 
    return 0;
}
 
// This code is contributed by pragup


Java




// Java program for the above approach
import java.util.*;
 
// A binary tree node
class Node
{
  int data;
  Node left, right;
  Node(int item)
  {
    data = item;
    left = right = null;
  }
}
 
class GFG
{
  Node root;
 
  // Function to find the maximum height
  // from leaf in the subtree rooted at
  // current node and add that to hashmap
  static int maxHeightToLeafUTIL(
    Node curr, Map<Integer, ArrayList<Integer> > mp)
  {
    if (curr == null)
    {
      return 0;
    }
 
    // Max height to leaf in left subtree
    int leftLeaf
      = maxHeightToLeafUTIL(curr.left, mp);
 
    // Max height to leaf in right subtree
    int rightLeaf
      = maxHeightToLeafUTIL(curr.right, mp);
 
    // Max height to leaf in current subtree
    int maxHeightSubtree
      = 1 + Math.max(leftLeaf, rightLeaf);
 
    // Adding current node to the Map
    if(!mp.containsKey(maxHeightSubtree))
    {
      mp.put(maxHeightSubtree, new ArrayList<>());  
    }
 
    mp.get(maxHeightSubtree).add(curr.data);
    return maxHeightSubtree;
  }
 
  // Function to find the count of leaf nodes
  // by repeatedly removing the leaf nodes
  static void printAndDelete(Node root)
  {
 
    // Stores the leaf deletion with
    // each iteration
    Map<Integer, ArrayList<Integer> > mp=new HashMap<>();
 
    // Function Call to find the order
    // of deletion of nodes
    maxHeightToLeafUTIL(root, mp);
 
    // Printing the map values
    for (Map.Entry<Integer,ArrayList<Integer>> k:mp.entrySet())
    {
      System.out.print(k.getValue().size() + " ");
    }
  }
 
  // Driver code
  public static void main (String[] args)
  {
 
    GFG tree = new GFG();
 
    tree.root = new Node(2);
    tree.root.left = new Node(5);
    tree.root.right = new Node(7);
    tree.root.right.right = new Node(6);
    tree.root.left.left = new Node(1);
    tree.root.left.right = new Node(8);
    tree.root.left.right.left = new Node(3);
    tree.root.left.right.right = new Node(4);
 
    /*
    Input :
         2
       /   \
      5     7
     / \     \
    1   8     6
       / \
      3   4
*/
 
    // Function Call
    printAndDelete(tree.root);
  }
}
 
// This code is contributed by offbeat


Python3




# Python3 program for the above approach
 
# Tree node structure used in the program
class Node:
     
    def __init__(self, x):
         
        self.data = x
        self.left = None
        self.right = None
 
# Function to find the maximum height
# from leaf in the subtree rooted at
# current node and add that to hashmap
def maxHeightToLeafUTIL(curr):
     
    global mp
 
    if (curr == None):
        return 0
 
    # Max height to leaf in left subtree
    leftLeaf = maxHeightToLeafUTIL(curr.left)
 
    # Max height to leaf in right subtree
    rightLeaf = maxHeightToLeafUTIL(curr.right)
 
    # Max height to leaf in current subtree
    maxHeightSubtree = 1 + max(leftLeaf, rightLeaf)
 
    # Adding current node to the Map
    mp[maxHeightSubtree].append(curr.data)
 
    return maxHeightSubtree
 
# Function to find the count of leaf nodes
# by repeatedly removing the leaf nodes
def printAndDelete(root):
     
    global mp
     
    # Function Call to find the order
    # of deletion of nodes
    maxHeightToLeafUTIL(root)
 
    for step in mp:
        if len(step):
            print(len(step), end = " ")
 
# Driver code
if __name__ == '__main__':
     
    mp = [[] for i in range(1000)]
     
    # Given Binary Tree
    root = Node(2)
    root.right = Node(7)
    root.right.right = Node(6)
    root.left = Node(5)
    root.left.left = Node(1)
    root.left.right = Node(8)
    root.left.right.left = Node(3)
    root.left.right.right = Node(4)
    #
    #    
    #     Input :
    #          2
    #        /   \
    #       5     7
    #      / \     \
    #     1   8     6
    #        / \
    #       3   4
 
    # Function Call
    printAndDelete(root)
     
# This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// A binary tree node
public class Node
{
  public int data;
  public Node left, right;
  public Node(int item)
  {
    data = item;
    left = right = null;
  }
}
 
public class GFG{
     
    Node root;
  
  // Function to find the maximum height
  // from leaf in the subtree rooted at
  // current node and add that to hashmap
  static int maxHeightToLeafUTIL(
    Node curr, Dictionary<int, List<int> > mp)
  {
    if (curr == null)
    {
      return 0;
    }
  
    // Max height to leaf in left subtree
    int leftLeaf
      = maxHeightToLeafUTIL(curr.left, mp);
  
    // Max height to leaf in right subtree
    int rightLeaf
      = maxHeightToLeafUTIL(curr.right, mp);
  
    // Max height to leaf in current subtree
    int maxHeightSubtree
      = 1 + Math.Max(leftLeaf, rightLeaf);
  
    // Adding current node to the Map
    if(!mp.ContainsKey(maxHeightSubtree))
    {
      mp.Add(maxHeightSubtree, new List<int>()); 
    }
  
    mp[maxHeightSubtree].Add(curr.data);
    return maxHeightSubtree;
  }
  
  // Function to find the count of leaf nodes
  // by repeatedly removing the leaf nodes
  static void printAndDelete(Node root)
  {
  
    // Stores the leaf deletion with
    // each iteration
    Dictionary<int, List<int> > mp=new Dictionary<int, List<int> >();
  
    // Function Call to find the order
    // of deletion of nodes
    maxHeightToLeafUTIL(root, mp);
  
    // Printing the map values
    foreach(KeyValuePair<int, List<int>> k in mp)
    {
      Console.Write(k.Value.Count + " ");
    }
  }
  
  // Driver code
     
    static public void Main (){
         
        GFG tree = new GFG();
  
    tree.root = new Node(2);
    tree.root.left = new Node(5);
    tree.root.right = new Node(7);
    tree.root.right.right = new Node(6);
    tree.root.left.left = new Node(1);
    tree.root.left.right = new Node(8);
    tree.root.left.right.left = new Node(3);
    tree.root.left.right.right = new Node(4);
  
    /*
    Input :
         2
       /   \
      5     7
     / \     \
    1   8     6
       / \
      3   4
*/
  
    // Function Call
    printAndDelete(tree.root);
    }
}


Javascript




<script>
 
    // JavaScript program to implement the above approach
     
    // Structure of a tree node
    class Node
    {
        constructor(item) {
           this.left = null;
           this.right = null;
           this.data = item;
        }
    }
     
    let root;
     
    class GFG
    {
        constructor() {
        }
    }
  
    // Function to find the maximum height
    // from leaf in the subtree rooted at
    // current node and add that to hashmap
    function maxHeightToLeafUTIL(curr, mp)
    {
      if (curr == null)
      {
        return 0;
      }
 
      // Max height to leaf in left subtree
      let leftLeaf
        = maxHeightToLeafUTIL(curr.left, mp);
 
      // Max height to leaf in right subtree
      let rightLeaf
        = maxHeightToLeafUTIL(curr.right, mp);
 
      // Max height to leaf in current subtree
      let maxHeightSubtree
        = 1 + Math.max(leftLeaf, rightLeaf);
 
      // Adding current node to the Map
      if(!mp.has(maxHeightSubtree))
      {
        mp.set(maxHeightSubtree, []); 
      }
 
      mp.get(maxHeightSubtree).push(curr.data);
      return maxHeightSubtree;
    }
 
    // Function to find the count of leaf nodes
    // by repeatedly removing the leaf nodes
    function printAndDelete(root)
    {
 
      // Stores the leaf deletion with
      // each iteration
      let mp = new Map();
 
      // Function Call to find the order
      // of deletion of nodes
      maxHeightToLeafUTIL(root, mp);
 
      // Printing the map values
      mp.forEach((values,keys)=>{
          document.write(values.length + " ")
      })
    }
     
    let tree = new GFG();
  
    tree.root = new Node(2);
    tree.root.left = new Node(5);
    tree.root.right = new Node(7);
    tree.root.right.right = new Node(6);
    tree.root.left.left = new Node(1);
    tree.root.left.right = new Node(8);
    tree.root.left.right.left = new Node(3);
    tree.root.left.right.right = new Node(4);
  
    /*
    Input :
         2
       /   \
      5     7
     / \     \
    1   8     6
       / \
      3   4
    */
  
    // Function Call
    printAndDelete(tree.root);
 
</script>


Output: 

4 2 1 1

 

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads