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++ 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 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 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# 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);
}
} |
<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> |
4 2 1 1
Time Complexity: O(N)
Auxiliary Space: O(N)