Given a Binary Tree, check if all leaves are at same level or not.
12
/ \
5 7
/ \
3 1
Leaves are at same level
12
/ \
5 7
/
3
Leaves are Not at same level
12
/
5
/ \
3 9
/ /
1 2
Leaves are at same level
The idea is to first find the level of the leftmost leaf and store it in a variable leafLevel. Then compare level of all other leaves with leafLevel, if same, return true, else return false. We traverse the given Binary Tree in a Preorder fashion. An argument leaflevel is passed to all calls. The value of leafLevel is initialized as 0 to indicate that the first leaf is not yet seen yet. The value is updated when we find first leaf. Level of subsequent leaves (in preorder) is compared with leafLevel.
Algorithm:
1.Define a function named checkUtil which takes in three arguments:
*A node of the binary tree.
*An integer level which represents the depth of the current node in the tree.
*A Leaf object named leafLevel which stores the level of the first leaf node found.
2.Check if the current node is null. If it is, return true.
3.Check if the current node is a leaf node by verifying that both its left and right children are null. If the node is a leaf:
*If it’s the first leaf node found, set the level of the first leaf node to the current level and return true.
*If it’s not the first leaf node found, compare its level to the level of the first leaf node found. Return true if they’re equal, false otherwise.
4.If the current node is not a leaf, recursively call checkUtil on its left and right children, incrementing the level by 1 for each call. Return true if both calls return true.
5.Define a function named check which takes in a single argument: a node of the binary tree.
6.Initialize the level variable to 0.
7.Create a Leaf object named mylevel which will store the level of the first leaf node found.
8.Call checkUtil on the root node of the tree, passing in the level, mylevel, and the root node.
9.Return the result of the checkUtil call. This will be true if all leaf nodes are at the same level, false otherwise.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *left, *right;
};
struct Node* newNode( int data)
{
struct Node* node = ( struct Node*) malloc ( sizeof ( struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
bool checkUtil( struct Node *root,
int level, int *leafLevel)
{
if (root == NULL) return true ;
if (root->left == NULL &&
root->right == NULL)
{
if (*leafLevel == 0)
{
*leafLevel = level;
return true ;
}
return (level == *leafLevel);
}
return checkUtil(root->left, level + 1, leafLevel) &&
checkUtil(root->right, level + 1, leafLevel);
}
bool check( struct Node *root)
{
int level = 0, leafLevel = 0;
return checkUtil(root, level, &leafLevel);
}
int main()
{
struct Node *root = newNode(12);
root->left = newNode(5);
root->left->left = newNode(3);
root->left->right = newNode(9);
root->left->left->left = newNode(1);
root->left->right->left = newNode(1);
if (check(root))
cout << "Leaves are at same level\n" ;
else
cout << "Leaves are not at same level\n" ;
getchar ();
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *left, *right;
};
struct Node* newNode( int data)
{
struct Node* node = ( struct Node*) malloc ( sizeof ( struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
bool check( struct Node *root)
{
int level = 0, leafLevel = 0;
return checkUtil(root, level, &leafLevel);
}
bool checkUtil( struct Node *root, int level, int *leafLevel)
{
if (root == NULL) return 1;
if (root->left == NULL && root->right == NULL)
{
if (*leafLevel == 0)
{
*leafLevel = level;
return true ;
}
return (level == *leafLevel);
}
return checkUtil(root->left, level+1, leafLevel) &&
checkUtil(root->right, level+1, leafLevel);
}
int main()
{
struct Node *root = newNode(12);
root->left = newNode(5);
root->left->left = newNode(3);
root->left->right = newNode(9);
root->left->left->left = newNode(1);
root->left->right->left = newNode(1);
if (check(root))
printf ( "Leaves are at same level\n" );
else
printf ( "Leaves are not at same level\n" );
getchar ();
return 0;
}
|
Java
class Node
{
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
class Leaf
{
int leaflevel= 0 ;
}
class BinaryTree
{
Node root;
Leaf mylevel = new Leaf();
boolean checkUtil(Node node, int level, Leaf leafLevel)
{
if (node == null )
return true ;
if (node.left == null && node.right == null )
{
if (leafLevel.leaflevel == 0 )
{
leafLevel.leaflevel = level;
return true ;
}
return (level == leafLevel.leaflevel);
}
return checkUtil(node.left, level + 1 , leafLevel)
&& checkUtil(node.right, level + 1 , leafLevel);
}
boolean check(Node node)
{
int level = 0 ;
return checkUtil(node, level, mylevel);
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 12 );
tree.root.left = new Node( 5 );
tree.root.left.left = new Node( 3 );
tree.root.left.right = new Node( 9 );
tree.root.left.left.left = new Node( 1 );
tree.root.left.right.left = new Node( 1 );
if (tree.check(tree.root))
System.out.println( "Leaves are at same level" );
else
System.out.println( "Leaves are not at same level" );
}
}
|
Python
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def checkUtil(root, level):
if root is None :
return True
if root.left is None and root.right is None :
if check.leafLevel = = 0 :
check.leafLevel = level
return True
return level = = check.leafLevel
return (checkUtil(root.left, level + 1 ) and
checkUtil(root.right, level + 1 ))
def check(root):
level = 0
check.leafLevel = 0
return (checkUtil(root, level))
root = Node( 12 )
root.left = Node( 5 )
root.left.left = Node( 3 )
root.left.right = Node( 9 )
root.left.left.left = Node( 1 )
root.left.right.left = Node( 2 )
if (check(root)):
print "Leaves are at same level"
else :
print "Leaves are not at same level"
|
C#
using System;
public class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
public class Leaf
{
public int leaflevel = 0;
}
class GFG
{
public Node root;
public Leaf mylevel = new Leaf();
public virtual bool checkUtil(Node node, int level,
Leaf leafLevel)
{
if (node == null )
{
return true ;
}
if (node.left == null && node.right == null )
{
if (leafLevel.leaflevel == 0)
{
leafLevel.leaflevel = level;
return true ;
}
return (level == leafLevel.leaflevel);
}
return checkUtil(node.left, level + 1, leafLevel) &&
checkUtil(node.right, level + 1, leafLevel);
}
public virtual bool check(Node node)
{
int level = 0;
return checkUtil(node, level, mylevel);
}
public static void Main( string [] args)
{
GFG tree = new GFG();
tree.root = new Node(12);
tree.root.left = new Node(5);
tree.root.left.left = new Node(3);
tree.root.left.right = new Node(9);
tree.root.left.left.left = new Node(1);
tree.root.left.right.left = new Node(1);
if (tree.check(tree.root))
{
Console.WriteLine( "Leaves are at same level" );
}
else
{
Console.WriteLine( "Leaves are not at same level" );
}
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .data = item;
this .left = this .right = null ;
}
}
class Leaf
{
leaflevel = 0;
}
let root;
let mylevel = new Leaf();
function checkUtil(node, level, leafLevel)
{
if (node == null )
return true ;
if (node.left == null && node.right == null )
{
if (leafLevel.leaflevel == 0)
{
leafLevel.leaflevel = level;
return true ;
}
return (level == leafLevel.leaflevel);
}
return checkUtil(node.left, level + 1, leafLevel) &&
checkUtil(node.right, level + 1, leafLevel);
}
function check(node)
{
let level = 0;
return checkUtil(node, level, mylevel);
}
root = new Node(12);
root.left = new Node(5);
root.left.left = new Node(3);
root.left.right = new Node(9);
root.left.left.left = new Node(1);
root.left.right.left = new Node(1);
if (check(root))
document.write( "Leaves are at same level" );
else
document.write( "Leaves are not at same level" );
</script>
|
OutputLeaves are at same level
Time Complexity: The function does a simple traversal of the tree, so the complexity is O(n).
Auxiliary Space: O(H) for call stack, where H is height of tree
Method 2 (Iterative): It can also be solved by an iterative approach.
The idea is to iteratively traverse the tree, and when you encounter the first leaf node, store its level in result variable, now whenever you encounter any leaf node, compare its level with previously stored result, they are the same then proceed for the rest of tree, else return false.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
};
Node* newNode( int data)
{
Node* temp = new Node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int checkLevelLeafNode(Node* root)
{
if (!root)
return 1;
queue<Node*> q;
q.push(root);
int flag = 0;
while (!q.empty()) {
int n = q.size();
for ( int i = 1; i <= n; i++) {
Node* temp = q.front();
q.pop();
if (temp->left) {
q.push(temp->left);
}
if (temp->right) {
q.push(temp->right);
}
if (temp->left == NULL && temp->right == NULL)
flag = 1;
}
if (flag && !q.empty())
return 0;
}
return 1;
}
int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(5);
root->right->right = newNode(6);
int result = checkLevelLeafNode(root);
if (result)
cout << "All leaf nodes are at same level\n" ;
else
cout << "Leaf nodes not at same level\n" ;
return 0;
}
|
Java
import java.util.*;
class Node {
int data;
Node left, right;
Node( int key) {
int data = key;
left = right = null ;
}
}
class GFG {
static boolean checkLevelLeafNode(Node root)
{
if (root == null )
return true ;
Queue<Node> q = new LinkedList<>();
q.add(root);
int result = Integer.MAX_VALUE;
int level = 0 ;
while (q.size() != 0 ) {
int size = q.size();
level++;
while (size > 0 ) {
Node temp = q.remove();
if (temp.left != null ) {
q.add(temp.left);
if (temp.left.left == null && temp.left.right == null ) {
if (result == Integer.MAX_VALUE)
result = level;
else if (result != level)
return false ;
}
}
if (temp.right != null ) {
q.add(temp.right);
if (temp.right.left == null && temp.right.right == null ) {
if (result == Integer.MAX_VALUE)
result = level;
else if (result != level)
return false ;
}
}
size--;
}
}
return true ;
}
public static void main(String args[])
{
Node root = new Node( 1 );
root.left = new Node( 2 );
root.right = new Node( 3 );
root.left.right = new Node( 4 );
root.right.left = new Node( 5 );
root.right.right = new Node( 6 );
boolean result = checkLevelLeafNode(root);
if (result == true )
System.out.println( "All leaf nodes are at same level" );
else
System.out.println( "Leaf nodes not at same level" );
}
}
|
Python3
INT_MAX = 2 * * 31
INT_MIN = - 2 * * 31
class newNode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def checkLevelLeafNode(root) :
if ( not root) :
return 1
q = []
q.append(root)
result = INT_MAX
level = 0
while ( len (q)):
size = len (q)
level + = 1
while (size > 0 or len (q)):
temp = q[ 0 ]
q.pop( 0 )
if (temp.left) :
q.append(temp.left)
if ( not temp.left.right and
not temp.left.left):
if (result = = INT_MAX):
result = level
elif (result ! = level):
return 0
if (temp.right) :
q.append(temp.right)
if ( not temp.right.left and
not temp.right.right):
if (result = = INT_MAX):
result = level
elif (result ! = level):
return 0
size - = 1
return 1
if __name__ = = '__main__' :
root = newNode( 1 )
root.left = newNode( 2 )
root.right = newNode( 3 )
root.left.right = newNode( 4 )
root.right.left = newNode( 5 )
root.right.right = newNode( 6 )
result = checkLevelLeafNode(root)
if (result) :
print ( "All leaf nodes are at same level" )
else :
print ( "Leaf nodes not at same level" )
|
C#
using System;
using System.Collections.Generic;
public class Node
{
public int data;
public Node left, right;
public Node( int key)
{
int data = key;
left = right = null ;
}
}
public class GFG
{
static bool checkLevelLeafNode(Node root)
{
if (root == null )
return true ;
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
int result = int .MaxValue;
int level = 0;
while (q.Count != 0)
{
int size = q.Count;
level++;
while (size > 0)
{
Node temp = q.Dequeue();
if (temp.left != null )
{
q.Enqueue(temp.left);
if (temp.left.left != null &&
temp.left.right != null )
{
if (result == int .MaxValue)
result = level;
else if (result != level)
return false ;
}
}
if (temp.right != null )
{
q.Enqueue(temp.right);
if (temp.right.left != null &&
temp.right.right != null )
{
if (result == int .MaxValue)
result = level;
else if (result != level)
return false ;
}
}
size--;
}
}
return true ;
}
public static void Main(String []args)
{
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.right = new Node(4);
root.right.left = new Node(5);
root.right.right = new Node(6);
bool result = checkLevelLeafNode(root);
if (result == true )
Console.WriteLine( "All leaf nodes are at same level" );
else
Console.WriteLine( "Leaf nodes not at same level" );
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .data = key;
this .left = this .right = null ;
}
}
function checkLevelLeafNode(root)
{
if (root == null )
return true ;
let q = [];
q.push(root);
let result = Number.MAX_VALUE;
let level = 0;
while (q.length != 0)
{
let size = q.length;
level++;
while (size > 0)
{
let temp = q.shift();
if (temp.left != null )
{
q.push(temp.left);
if (temp.left.left == null &&
temp.left.right == null )
{
if (result == Number.MAX_VALUE)
result = level;
else if (result != level)
return false ;
}
}
if (temp.right != null )
{
q.push(temp.right);
if (temp.right.left == null &&
temp.right.right == null )
{
if (result == Number.MAX_VALUE)
result = level;
else if (result != level)
return false ;
}
}
size--;
}
}
return true ;
}
let root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.right = new Node(4);
root.right.left = new Node(5);
root.right.right = new Node(6);
let result = checkLevelLeafNode(root);
if (result == true )
document.write( "All leaf nodes are at same level" );
else
document.write( "Leaf nodes not at same level" );
</script>
|
OutputAll leaf nodes are at same level
Time Complexity: O(n)
Auxiliary Space: O(n)
Method 3 : One point to note down is that if all the leaf nodes are at the same level then the distance of all the leaf nodes from the root node will be the same. Now, assume that there are two leaf nodes leafA and leafB at distance distA and distB respectively from the root node. Here distA < distB. The node leaf A is closer to the root than leafB.
Now, suppose max_dist and min_dist represent the maximum distance and minimum distance out of all the distances of all the leaf nodes from the root node. Now in the above situation of the leaf nodes leafA and leafB, max_dist will not be equal to min_dist because distA < distB. So we can also say that if max_dist is equal to min_dist then all the leaf nodes are at same level else the leaf nodes are not at the same level.
So we will find max_dist and min_dist for a given binary tree. If max_dist is equal to min_dist then all the leaf nodes are at the same level else the leaf nodes are not at the same level.
Algorithm :
1) Finding the max_dist is similar to finding the height of the given tree. You can read the following article for the solution
https://www.geeksforgeeks.org/find-the-maximum-depth-or-height-of-a-tree/
2)The approach for finding min_dist will be almost similar to finding max_dist.We will use a recursive approach
3) Now for finding the min_dist, assume a function minDist() which takes root node as input and returns min_dist.
4) Now the given node will ask for the minimum distance from its adjacent left node of the left subtree say left_dist and the minimum distance from its adjacent right node of the right subtree say right_dist.
5) Now there are basically 4 types of node
5.1) If a node has left and right node as null, then it will return 1
5.2) If a node has the left node as null, then it will ignore the left null node. We can assume that the left node is at a distance of infinity. Here left_dist will be infinity.
5.3) If a node has the right node as null, then it will ignore the right null node. We can assume that the right node is at a distance of infinity. Here right_dist will be infinity.
5.4) If a node has both right and left nodes then it will get the left_dist and right_dist.
6) Now after getting the right_dist and left_dist the given node will return min( right_dist , left_dist) + 1. Here we are taking a minimum of left_dist and right_dist because we have to find the minimum distance of the leaf node from the root. We are adding 1 because the current node also needs to be counted.
Now after getting max_dist and min_dist, if they are equal we will return true. If they are not equal we will return false.
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
class Node {
public :
int data;
Node *left, *right;
Node( int item)
{
data = item;
left = right = NULL;
}
};
int maxDist(Node* curr)
{
if (curr == NULL)
return 0;
int left_dist = maxDist(curr->left);
int right_dist = maxDist(curr->right);
return 1 + max(left_dist, right_dist);
}
int minDist(Node* curr)
{
if (curr == NULL)
return INT_MAX;
if (curr->left == NULL && curr->right == NULL)
return 1;
int left_dist = minDist(curr->left);
int right_dist = minDist(curr->right);
return 1 + min(left_dist, right_dist);
}
int main()
{
Node* root = new Node(12);
root->left = new Node(5);
(root->left)->left = new Node(3);
(root->left)->right = new Node(9);
((root->left)->left)->left = new Node(1);
((root->left)->right)->left = new Node(1);
int max_dist = maxDist(root);
int min_dist = minDist(root);
if (max_dist == min_dist)
cout << "Leaves are at same level" << endl;
else
cout << "Leaves are not at same level" << endl;
}
|
Java
import java.io.*;
class Node {
int data;
Node left, right;
Node( int item)
{
data = item;
left = right = null ;
}
}
public class GFG {
public static void main(String[] args)
{
Node root = new Node( 12 );
root.left = new Node( 5 );
root.left.left = new Node( 3 );
root.left.right = new Node( 9 );
root.left.left.left = new Node( 1 );
root.left.right.left = new Node( 1 );
int max_dist = maxDist(root);
int min_dist = minDist(root);
if (max_dist == min_dist)
System.out.println( "Leaves are at same level" );
else
System.out.println(
"Leaves are not at same level" );
}
static int maxDist(Node curr)
{
if (curr == null )
return 0 ;
int left_dist = maxDist(curr.left);
int right_dist = maxDist(curr.right);
return 1 + Math.max(left_dist, right_dist);
}
static int minDist(Node curr)
{
if (curr == null )
return Integer.MAX_VALUE;
if (curr.left == null && curr.right == null )
return 1 ;
int left_dist = minDist(curr.left);
int right_dist = minDist(curr.right);
return 1 + Math.min(left_dist, right_dist);
}
}
|
Python3
import sys
class Node:
def __init__( self , data, left = None , right = None ):
self .data = data
self .left = left
self .right = right
def maxDist(curr):
if (curr = = None ):
return 0
left_dist = maxDist(curr.left)
right_dist = maxDist(curr.right)
return 1 + max (left_dist, right_dist)
def minDist(curr):
if (curr = = None ):
return sys.maxsize
if ((curr.left = = None ) and (curr.right = = None )):
return 1
left_dist = minDist(curr.left)
right_dist = minDist(curr.right)
return 1 + min (left_dist, right_dist)
root = Node( 12 )
root.left = Node( 5 )
root.left.left = Node( 3 )
root.left.right = Node( 9 )
root.left.left.left = Node( 1 )
root.left.right.left = Node( 1 )
maxDist = maxDist(root)
min_dist = minDist(root)
if maxDist = = minDist:
print ( 'leaves are at same level' )
else :
print ( 'Leaves are not at same level' )
|
C#
using System;
class Node
{
public int data;
public Node left, right;
public Node( int item)
{
data = item;
left = right = null ;
}
}
class Program
{
static int maxDist(Node curr)
{
if (curr == null )
return 0;
int left_dist = maxDist(curr.left);
int right_dist = maxDist(curr.right);
return 1 + Math.Max(left_dist, right_dist);
}
static int minDist(Node curr)
{
if (curr == null )
return Int32.MaxValue;
if (curr.left == null && curr.right == null )
return 1;
int left_dist = minDist(curr.left);
int right_dist = minDist(curr.right);
return 1 + Math.Min(left_dist, right_dist);
}
static void Main( string [] args)
{
Node root = new Node(12);
root.left = new Node(5);
root.left.left = new Node(3);
root.left.right = new Node(9);
root.left.left.left = new Node(1);
root.left.right.left = new Node(1);
int max_dist = maxDist(root);
int min_dist = minDist(root);
if (max_dist == min_dist)
Console.WriteLine( "Leaves are at same level" );
else
Console.WriteLine( "Leaves are not at same level" );
}
}
|
Javascript
class Node {
constructor(item) {
this .data = item;
this .left = null ;
this .right = null ;
}
}
function maxDist(curr)
{
if (curr === null )
{
return 0;
}
const leftDist = maxDist(curr.left);
const rightDist = maxDist(curr.right);
return 1 + Math.max(leftDist, rightDist);
}
function minDist(curr)
{
if (curr === null )
{
return Number.MAX_SAFE_INTEGER;
}
if (curr.left === null && curr.right === null )
{
return 1;
}
const leftDist = minDist(curr.left);
const rightDist = minDist(curr.right);
return 1 + Math.min(leftDist, rightDist);
}
const root = new Node(12);
root.left = new Node(5);
root.left.left = new Node(3);
root.left.right = new Node(9);
root.left.left.left = new Node(1);
root.left.right.left = new Node(1);
const maxDistResult = maxDist(root);
const minDistResult = minDist(root);
if (maxDistResult === minDistResult)
{
console.log( 'Leaves are at same level' );
}
else
{
console.log( 'Leaves are not at same level' );
}
|
OutputLeaves are at same level
Time Complexity : O(n)
Auxiliary Space : O(n)