Check if a given tree has all leaves at same level or not

In this article, we are going to check whether all leaves of the given tree is at the same level or not.
Submitted by Radib Kar, on August 07, 2020

The leave nodes are the nodes that don't have any children. Now a tree can have all leaves at the same level or not. We can check that using both recursive and iterative algorithms. Below is a detailed explanation of both the approaches & also we have added examples to understand how the algorithm is working.

Example 1:

given tree has all leaves at same level or not (1)

Figure 1: Example 1 where all leaf nodes are at the same level

In the above example, all the leaf nodes are marked with a double circle and we can see those are at the same level (Level 1).

Example 2:

given tree has all leaves at same level or not (2)

Figure 1: Example 1 where all leaf nodes are not at the same level

In the above example, all the leaf nodes are marked with a double circle and we can see all are not at the same level (one is at Level 1 and another is at level 2).

1) Recursive approach

In the recursive method, we can calculate the level of all leaf nodes and can store that in the hash table. Then in the second pass, we will check whether all leaf nodes have the same level or not from the hash table. So, after the first pass, we will have our hash table storing all leaf nodes along with their depth. The height() function in the below implementation is computing the levels of the leaf nodes recursively and storing them in the hashmap. Then in the second pass, we have checked whether all leaf nodes are at the same level or not. Below is the detailed implementation:

C++ Implementation:

#include <bits/stdc++.h>
using namespace std;

// tree node is defined
class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int data)
    {
        val = data;
        left = NULL;
        right = NULL;
    }
};

void height(int level, TreeNode* root, unordered_map<TreeNode*, int>& mymap)
{
    //base case
    if (!root)
        return;

    //if current node is a leaf node
    //store it along with the current level in the hash table
    if (!root->left && !root->right) {
        mymap[root] = level;
        return;
    }

    //for the next level
    height(level + 1, root->left, mymap);
    height(level + 1, root->right, mymap);
}
bool checkAllLeavesAtSameLevel(TreeNode* root)
{
    //Your code here
    if (!root)
        return true;
    //first pass to store the leaf nodes along with their levels
    unordered_map<TreeNode*, int> mymap;
    height(0, root, mymap);

    //take height of any leaf node and make that bench mark
    int bench_mark = (mymap.begin())->second;
    //comapre other leaf node levels with the bench mark
    //if any leaf node violates, return false
    for (auto it = mymap.begin(); it != mymap.end(); it++) {
        if (it->second != bench_mark)
            return false;
    }
    //if all leaf nodes are at same level return true
    return true;
}

int main()
{
    //building the tree like example 1
    TreeNode* root1 = new TreeNode(1);
    
    root1->left = new TreeNode(2);
    root1->right = new TreeNode(3);

    if (checkAllLeavesAtSameLevel(root1))
        cout << "Tree in example1 has all leaves at same level\n";
    else
        cout << "Tree in example1 doesn't has all leaves at same level\n";

    //building the tree-like example 2
    TreeNode* root2 = new TreeNode(1);
    root2->left = new TreeNode(2);
    root2->right = new TreeNode(3);
    root2->left->left = new TreeNode(4);

    if (checkAllLeavesAtSameLevel(root2))
        cout << "Tree in example2 has all leaves at same level\n";
    else
        cout << "Tree in example2 doesn't has all leaves at same level\n";
    
    return 0;
}

Output:

Tree in example1 has all leaves at same level
Tree in example2 doesn't has all leaves at same level

The time complexity of the above is O(n) and storage complexity is O(L) where L is the number of leaf nodes.

If we dry run, we will see that for the first example, after the first pass, we will have our hash table like below:

Key	                    Value
Tree Node with value 2	    1
Tree Node with value 3	    1

So all keys have the same value and hence the tree has all its leaves at the same level.

For the second example, after the first pass, we will have our hash table like below:

Key	                    Value
Tree Node with value 3	    1
Tree Node with value 4	    2

So we found that all keys don’t have the same value which means that all leaves are not at the same level.

2) Iterative approach(Using level order traversal)

We can also use iterative algorithms using level order traversal to solve this problem. The idea is to do a level order traversal and as soon as we find a leaf node, we set the benchmark to the current level where we find the leaf node. Then we keep traversing level wise and for each leaf node found, we check whether the current traversing level is the same as the benchmark level or not. Below is the detailed implementation.

C++ Implementation:

#include <bits/stdc++.h>
using namespace std;

// tree node is defined
class TreeNode {
public:
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int data)
    {
        val = data;
        left = NULL;
        right = NULL;
    }
};

void height(int level, TreeNode* root, unordered_map<TreeNode*, int>& mymap)
{
    //base case
    if (!root)
        return;

    //if current node is a leaf node
    //store it along with the current level in the hash table
    if (!root->left && !root->right) {
        mymap[root] = level;
        return;
    }

    //for the next level
    height(level + 1, root->left, mymap);
    height(level + 1, root->right, mymap);
}

bool checkAllLeavesAtSameLevel(TreeNode* root)
{
    int bench_mark = INT_MIN;
    int cur_level = 0;
 
    queue<TreeNode*> q;
 
    q.push(root);
    q.push(NULL);
 
    //while queue is not empty
    while (!q.empty()) {
        TreeNode* cur_node = q.front();
        q.pop();
        //if DeQued element is NULL
        //that means end of last level
        if (!cur_node) {
            //increment the cure=rent level
            cur_level++;
            //if queue is not empty that means there are 
            //cuurent level nodes
            if (!q.empty()) {
                //add NULL to indicqate end of current level
                q.push(NULL);
            }
        }
        else {
            //if current node is leaf node
            if (!cur_node->left && !cur_node->right) {
                //if bench mark is not set yet
                if (bench_mark == INT_MIN) {
                    //first leaf node found
                    //set the bench mark as current level

                    bench_mark = cur_level;
                }
                else {
                    //for further leaf nodes check the bench mark same 
                    //with current level or not
                    if (cur_level != bench_mark)
                        return false;
                }
            }
            if (cur_node->left)
                q.push(cur_node->left);
            if (cur_node->right)
                q.push(cur_node->right);
        }
    }

    return true;
}

int main()
{
    //building the tree like example 1
    TreeNode* root1 = new TreeNode(1);
    
    root1->left = new TreeNode(2);
    root1->right = new TreeNode(3);

    if (checkAllLeavesAtSameLevel(root1))
        cout << "Tree in example1 has all leaves at same level\n";
    else
        cout << "Tree in example1 doesn't has all leaves at same level\n";

    //building the tree-like example 2
    TreeNode* root2 = new TreeNode(1);
    
    root2->left = new TreeNode(2);
    root2->right = new TreeNode(3);
    root2->left->left = new TreeNode(4);

    if (checkAllLeavesAtSameLevel(root2))
        cout << "Tree in example2 has all leaves at same level\n";
    else
        cout << "Tree in example2 doesn't has all leaves at same level\n";
    
    return 0;
}

Output:

Tree in example1 has all leaves at same level
Tree in example2 doesn't has all leaves at same level





Comments and Discussions

Ad: Are you a blogger? Join our Blogging forum.





Languages: » C » C++ » C++ STL » Java » Data Structure » C#.Net » Android » Kotlin » SQL
Web Technologies: » PHP » Python » JavaScript » CSS » Ajax » Node.js » Web programming/HTML
Solved programs: » C » C++ » DS » Java » C#
Aptitude que. & ans.: » C » C++ » Java » DBMS
Interview que. & ans.: » C » Embedded C » Java » SEO » HR
CS Subjects: » CS Basics » O.S. » Networks » DBMS » Embedded Systems » Cloud Computing
» Machine learning » CS Organizations » Linux » DOS
More: » Articles » Puzzles » News/Updates


© https://www.includehelp.com some rights reserved.