Minimum nodes to be removed to make a Binary tree complete
Last Updated :
27 Apr, 2023
Given a binary tree with positive values of nodes, find the minimum number of nodes that need to be removed to transform it into a complete binary tree. Return 0 if the given tree is already complete.
Note: A complete binary tree is a special type of binary tree where all the levels of the tree are filled completely except possibly the lowest level nodes which are filled from as left as possible.
Examples:
Input:
Input example tree 1
Output: 1
Explanation: If we remove node 6, it will transform into the complete binary tree. Note that we could also remove all the nodes of the last level which will also convert it to complete but it will not be the minimum.
Input:
Input example tree 2
Output: 3
Explanation: Nodes 6, 7, and 8 are to be removed.
Approach: To solve the problem using BFS (Breadth First Search) follow the below idea:
Using BFS (Breadth First Search): BFS is the most intuitive algorithm here. We will traverse through each level of the given binary tree and when we find the first null node after that all other nodes have to be removed (if present) to convert it to a complete binary tree, So we will count those nodes and return it as our answer.
Steps that were to follow the above approach:
- Start the BFS traversal with the root node.
- To keep track of the null node create a boolean “nullFound” with starting value of false.
- Now when the first null node is found make “nullFound” true.
- As soon as “nullFound” becomes true, count all preceding nodes of the same level as well as of below levels.
Below is the code to implement the above steps:
C++
#include <bits/stdc++.h>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode( int x)
: val(x), left(NULL), right(NULL)
{
}
};
int minNodesToBeRemoved_bfs(TreeNode* root)
{
if (!root)
return 0;
queue<TreeNode*> q;
q.push(root);
bool nullFound = false ;
int ans = 0;
while (q.size()) {
auto front = q.front();
q.pop();
if (front->left) {
q.push(front->left);
if (nullFound)
ans++;
}
else
nullFound = true ;
if (front->right) {
q.push(front->right);
if (nullFound)
ans++;
}
else
nullFound = true ;
}
return ans;
}
int main()
{
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->right = new TreeNode(6);
root->left->right->left = new TreeNode(7);
root->left->right->right = new TreeNode(8);
cout << "Minimum number of nodes to be removed to make "
"the tree complete is: " ;
cout << minNodesToBeRemoved_bfs(root) << endl;
return 0;
}
|
Python3
from queue import Queue
class TreeNode:
def __init__( self , x):
self .val = x
self .left = None
self .right = None
def minNodesToBeRemoved_bfs(root: TreeNode) - > int :
if not root:
return 0
q = Queue()
q.put(root)
nullFound = False
ans = 0
while not q.empty():
front = q.get()
if front.left:
q.put(front.left)
if nullFound:
ans + = 1
else :
nullFound = True
if front.right:
q.put(front.right)
if nullFound:
ans + = 1
else :
nullFound = True
return ans
if __name__ = = '__main__' :
root = TreeNode( 1 )
root.left = TreeNode( 2 )
root.right = TreeNode( 3 )
root.left.left = TreeNode( 4 )
root.left.right = TreeNode( 5 )
root.right.right = TreeNode( 6 )
root.left.right.left = TreeNode( 7 )
root.left.right.right = TreeNode( 8 )
print ( "Minimum number of nodes to be removed to make "
"the tree complete is: " , minNodesToBeRemoved_bfs(root))
|
C#
using System;
using System.Collections.Generic;
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
public class Solution
{
public static int minNodesToBeRemoved_bfs(TreeNode root)
{
if (root == null )
return 0;
Queue<TreeNode> q = new Queue<TreeNode>();
q.Enqueue(root);
bool nullFound = false ;
int ans = 0;
while (q.Count > 0)
{
var front = q.Dequeue();
if (front.left != null )
{
q.Enqueue(front.left);
if (nullFound)
ans++;
}
else
nullFound = true ;
if (front.right != null )
{
q.Enqueue(front.right);
if (nullFound)
ans++;
}
else
nullFound = true ;
}
return ans;
}
static void Main()
{
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(8);
Console.Write( "Minimum number of nodes to be removed to make " +
"the tree complete is: " );
Console.WriteLine(minNodesToBeRemoved_bfs(root));
}
}
|
Java
import java.util.LinkedList;
import java.util.Queue;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
public class GFG {
public static int minNodesToBeRemoved_bfs(TreeNode root)
{
if (root == null )
return 0 ;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
boolean nullFound = false ;
int ans = 0 ;
while (!q.isEmpty()) {
TreeNode front = q.poll();
if (front.left != null ) {
q.offer(front.left);
if (nullFound)
ans++;
}
else
nullFound = true ;
if (front.right != null ) {
q.offer(front.right);
if (nullFound)
ans++;
}
else
nullFound = true ;
}
return ans;
}
public static void main(String[] args)
{
TreeNode root = new TreeNode( 1 );
root.left = new TreeNode( 2 );
root.right = new TreeNode( 3 );
root.left.left = new TreeNode( 4 );
root.left.right = new TreeNode( 5 );
root.right.right = new TreeNode( 6 );
root.left.right.left = new TreeNode( 7 );
root.left.right.right = new TreeNode( 8 );
System.out.print(
"Minimum number of nodes to be removed to make the tree complete is: " );
System.out.println(minNodesToBeRemoved_bfs(root));
}
}
|
Javascript
class TreeNode {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
function minNodesToBeRemoved_bfs(root) {
if (!root)
return 0;
const q = [];
q.push(root);
let nullFound = false ;
let ans = 0;
while (q.length) {
const front = q.shift();
if (front.left) {
q.push(front.left);
if (nullFound)
ans++;
}
else
nullFound = true ;
if (front.right) {
q.push(front.right);
if (nullFound)
ans++;
}
else
nullFound = true ;
}
return ans;
}
(() => {
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(8);
console.log( "Minimum number of nodes to be removed to make the tree complete is: " );
console.log(minNodesToBeRemoved_bfs(root));
})();
|
Output
Minimum number of nodes to be removed to make the tree complete is: 3
Time Complexity: O(n), (n is the number of nodes) because we are traversing through all the nodes.
Auxiliary Space: O(n), (n is the number of nodes) queue is used to contain all the nodes.
Approach:
Using DFS (Depth First Search): Using DFS for this problem is a little bit tricky. We can not directly check, at which level the first null node is found as in the above approach. So we will create an array and store the elements of the given tree (level-wise) in it, at a specific index such that if the tree was complete all the nodes would be filled in the array before a null appears. After the first null node is found the count of all the preceding nodes is our answer.
Steps that were to follow the above approach:
- Find the height of the binary tree ‘h’ using DFS.
- For a complete tree, the maximum nodes can be (2h – 1).
- Create an array of size (2h – 1) to store nodes level-wise.
- Now start the DFS with root and keep filling the array.
- For all, DFS calls if the root is at index “idx” put the left node at index 2*idx+1 and the right node at 2*idx+2.
- Now traverse through the array and keep a track of the first null node.
- If there are any other nodes after the first null node count them and return.
Illustration of the above steps:
Given Tree:
1
/ \
2 3
/ \ \
4 5 6
/ \
7 8
- Height of the tree: 4, Maximum possible Nodes : 24 – 1 = 15.
- Initial Array: |-1| |-1| |-1| |-1| ….. 15 blocks.
- Array after DFS traversal: |1| |2| |3| |4| |5| |-1| |6| |-1| |-1| |7| |8| |-1| |-1| |-1| |-1|.
- The first null node found at index 5 after that nodes 6, 7 and 8 are present. So the answer is 3.
Below is the code to implement the above steps:
C++
#include <bits/stdc++.h>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode( int x)
: val(x), left(NULL), right(NULL)
{
}
};
int height(TreeNode* root)
{
if (!root)
return 0;
return 1 + max(height(root->left), height(root->right));
}
void dfs(TreeNode* root, int index, vector< int >& arr)
{
if (!root)
return ;
arr[index] = root->val;
dfs(root->left, 2 * index + 1, arr);
dfs(root->right, 2 * index + 2, arr);
}
int minNodesToBeRemoved_dfs(TreeNode* root)
{
int h = height(root);
int maxNodes = (1 << h) - 1;
vector< int > arr(maxNodes, -1);
dfs(root, 0, arr);
bool nullFound = false ;
int ans = 0;
for ( auto & it : arr) {
if (it == -1)
nullFound = true ;
if (nullFound && it != -1)
ans++;
}
return ans;
}
int main()
{
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->right = new TreeNode(6);
root->left->right->left = new TreeNode(7);
root->left->right->right = new TreeNode(8);
cout << "Minimum number of nodes to be removed to make "
"the tree complete is: " ;
cout << minNodesToBeRemoved_dfs(root) << endl;
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode( int x)
{
val = x;
left = null ;
right = null ;
}
}
static int height(TreeNode root)
{
if (root == null )
return 0 ;
return 1
+ Math.max(height(root.left),
height(root.right));
}
static void dfs(TreeNode root, int index, int [] arr)
{
if (root == null )
return ;
arr[index] = root.val;
dfs(root.left, 2 * index + 1 , arr);
dfs(root.right, 2 * index + 2 , arr);
}
static int minNodesToBeRemoved_dfs(TreeNode root)
{
int h = height(root);
int maxNodes = ( 1 << h) - 1 ;
int [] arr = new int [maxNodes];
Arrays.fill(arr, - 1 );
dfs(root, 0 , arr);
boolean nullFound = false ;
int ans = 0 ;
for ( int i = 0 ; i < arr.length; i++) {
int it = arr[i];
if (it == - 1 )
nullFound = true ;
if (nullFound && it != - 1 )
ans++;
}
return ans;
}
public static void main(String[] args)
{
TreeNode root = new TreeNode( 1 );
root.left = new TreeNode( 2 );
root.right = new TreeNode( 3 );
root.left.left = new TreeNode( 4 );
root.left.right = new TreeNode( 5 );
root.right.right = new TreeNode( 6 );
root.left.right.left = new TreeNode( 7 );
root.left.right.right = new TreeNode( 8 );
System.out.print(
"Minimum number of nodes to be removed to make the tree complete is: " );
System.out.println(minNodesToBeRemoved_dfs(root));
}
}
|
Python3
class TreeNode:
def __init__( self , x):
self .val = x
self .left = None
self .right = None
def height(root):
if not root:
return 0
return 1 + max (height(root.left), height(root.right))
def dfs(root, index, arr):
if not root:
return
arr[index] = root.val
dfs(root.left, 2 * index + 1 , arr)
dfs(root.right, 2 * index + 2 , arr)
def minNodesToBeRemoved_dfs(root):
h = height(root)
maxNodes = ( 1 << h) - 1
arr = [ - 1 ] * maxNodes
dfs(root, 0 , arr)
nullFound = False
ans = 0
for it in arr:
if it = = - 1 :
nullFound = True
if nullFound and it ! = - 1 :
ans + = 1
return ans
if __name__ = = "__main__" :
root = TreeNode( 1 )
root.left = TreeNode( 2 )
root.right = TreeNode( 3 )
root.left.left = TreeNode( 4 )
root.left.right = TreeNode( 5 )
root.right.right = TreeNode( 6 )
root.left.right.left = TreeNode( 7 )
root.left.right.right = TreeNode( 8 )
print ( "Minimum number of nodes to be removed to make the tree complete is: " )
print (minNodesToBeRemoved_dfs(root))
|
C#
using System;
using System.Collections.Generic;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode( int x) {
val = x;
left = null ;
right = null ;
}
}
public class Solution {
public int Height(TreeNode root) {
if (root == null ) {
return 0;
}
return 1 + Math.Max(Height(root.left), Height(root.right));
}
public void Dfs(TreeNode root, int index, List< int > arr) {
if (root == null ) {
return ;
}
arr[index] = root.val;
Dfs(root.left, 2 * index + 1, arr);
Dfs(root.right, 2 * index + 2, arr);
}
public int MinNodesToBeRemoved(TreeNode root) {
int h = Height(root);
int maxNodes = (1 << h) - 1;
List< int > arr = new List< int >(maxNodes);
for ( int i = 0; i < maxNodes; i++) {
arr.Add(-1);
}
Dfs(root, 0, arr);
bool nullFound = false ;
int ans = 0;
foreach ( int it in arr) {
if (it == -1) {
nullFound = true ;
}
if (nullFound && it != -1) {
ans++;
}
}
return ans;
}
static void Main() {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(8);
Console.Write( "Minimum number of nodes to be removed to make " +
"the tree complete is: " );
Console.WriteLine( new Solution().MinNodesToBeRemoved(root));
}
}
|
Javascript
class TreeNode {
constructor(val) {
this .val = val;
this .left = null ;
this .right = null ;
}
}
function height(root) {
if (!root) {
return 0;
}
return 1 + Math.max(height(root.left), height(root.right));
}
function dfs(root, index, arr) {
if (!root) {
return ;
}
arr[index] = root.val;
dfs(root.left, 2 * index + 1, arr);
dfs(root.right, 2 * index + 2, arr);
}
function minNodesToBeRemoved_dfs(root) {
const h = height(root);
const maxNodes = (1 << h) - 1;
const arr = new Array(maxNodes).fill(-1);
dfs(root, 0, arr);
let nullFound = false ;
let ans = 0;
for (let i = 0; i < arr.length; i++) {
const it = arr[i];
if (it === -1) {
nullFound = true ;
}
if (nullFound && it !== -1) {
ans++;
}
}
return ans;
}
function main() {
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.right = new TreeNode(6);
root.left.right.left = new TreeNode(7);
root.left.right.right = new TreeNode(8);
console.log(
"Minimum number of nodes to be removed to make " +
"the tree complete is: " +
minNodesToBeRemoved_dfs(root)
);
}
main();
|
Output
Minimum number of nodes to be removed to make the tree complete is: 3
Time Complexity: O(2^h-1), where h is the height of the tree.
Auxiliary Space: O(2^h-1)
Share your thoughts in the comments
Please Login to comment...