Open In App

Find all duplicate levels of given Binary Tree

Improve
Improve
Like Article
Like
Save
Share
Report

A binary tree is a tree data structure in which each node has at most two child nodes, referred to as the left and right children. In this question, the task is to find all the duplicate levels of a given binary tree. This problem can be used to identify and resolve any duplicate nodes or values in the tree, ensuring that the tree structure remains valid. This can be useful in various applications such as databases or file systems, where duplicate values can lead to inconsistencies and errors in the data. By finding and removing duplicate levels in a binary tree, we can ensure the integrity and accuracy of the data stored in the tree.

Given the root of a binary tree in which all nodes has values 0 or 1, the task is to find and print all levels for which another level exists such that the decimal representation of each is same. If no such level exists, return an empty list. 

Examples:

Input: 
               1                      
           /      \                   
         0        1                 
       / \       /             
    1    0   1    
        /   \
      0     1
    /
  1
Output:  {3, 1}, {4, 0}
Explanation:  Level 3 is duplicate of level 1
Level 4 is duplicate of level 0

Input: 1
Output: { }

 

Approach: The idea is to solve the problem is based on the following observation:

The idea is to perform levelorder traversal of given Tree and for each level, convert the binary representation to decimal and store in an int variable. Then the problem will be converted to simply find all duplicate elements in given array.

To solve the problem of finding duplicate levels in a binary tree:

  • Perform a level-order traversal of the binary tree, starting from the root node and ending at the leaf nodes.
  • For each level, convert it to its decimal equivalent representation and store the value in a map, using the format {decimal_number, level_number}.
  • Check if there are multiple levels associated with a single decimal key. If so, these levels are duplicates and should be printed.
  • If there are no duplicate levels found in the binary tree, return an empty list.

By following these steps, you can effectively find and identify any duplicate levels in a binary tree, helping to ensure the integrity and accuracy of the data stored within the tree.

Below is the implementation of the above approach:

C++14




#include <bits/stdc++.h>
 
using namespace std;
 
// Class containing left and right
// child of current node and key value
struct Node {
    int data;
    Node *left, *right;
    Node(int item)
    {
        data = item;
        left = right = NULL;
    }
};
 
struct LevelInfo {
    int level;
    int length;
};
 
class Solution {
public:
    Node* root;
    unordered_map<int, vector<LevelInfo>> duplicateMap;
 
    Solution(Node* root) {
        this->root = root;
    }
 
    vector<vector<int>> printDuplicateLevels() {
        int h = height(root);
        int i;
 
        vector<vector<int>> dup_levels;
 
        // Initialize for the root level
        LevelInfo zerolevelInfo = {0, 0};
        duplicateMap[root->data] = {zerolevelInfo};
 
        for (i = 1; i <= h; i++) {
            vector<int> currentLevel;
            getCurrentLevel(root, i, currentLevel);
            bitset<32> bits(getDecimalValue(currentLevel));
 
            int decimalValue = bits.to_ulong();
 
            LevelInfo currentlevelInfo = {i - 1, (int)currentLevel.size()};
 
            if (duplicateMap.find(decimalValue) != duplicateMap.end()) {
                auto& vec = duplicateMap[decimalValue];
                auto it = find_if(vec.begin(), vec.end(),
                    [&](const LevelInfo& l) { return l.length == currentLevel.size(); });
                if (it != vec.end()) {
                    vector<int> dup_level_curr = {i - 1, it->level};
                    dup_levels.push_back(dup_level_curr);
                }
                else {
                    duplicateMap[decimalValue].push_back(currentlevelInfo);
                }
            }
            else {
                duplicateMap[decimalValue] = {currentlevelInfo};
            }
        }
 
        return dup_levels;
    }
 
 
    // Compute the "height" of a
    int height(Node* root) {
        if (root == nullptr) {
            return 0;
        }
        else {
            // Compute height of each sub
            int lheight = height(root->left);
            int rheight = height(root->right);
 
            // Use the larger one
            if (lheight > rheight) {
                return (lheight + 1);
            }
            else {
                return (rheight + 1);
            }
        }
    }
 
    // Get nodes at the current level
    void getCurrentLevel(Node* root, int level, vector<int>& currentLevel) {
        if (root == nullptr) {
            return;
        }
        if (level == 1) {
            currentLevel.push_back(root->data);
        }
        else if (level > 1) {
            getCurrentLevel(root->left, level - 1, currentLevel);
            getCurrentLevel(root->right, level - 1, currentLevel);
        }
    }
 
    int getDecimalValue(const vector<int>& currentLevel) {
        int decimalValue = 0;
        for (int i = 0; i < currentLevel.size(); i++) {
            decimalValue += (currentLevel[i] << (currentLevel.size() - 1 - i));
        }
        return decimalValue;
    }
};
int main() {
    // create the binary
    Node* root = new Node(1);
    root->left = new Node(0);
    root->right = new Node(1);
    root->left->left = new Node(1);
    root->left->right = new Node(0);
    root->right->left = new Node(1);
    root->left->right->left = new Node(0);
    root->right->left->right = new Node(1);
    root->left->right->left->left = new Node(1);
 
    // print the duplicate levels
    Solution* sol = new Solution(root);
    vector<vector<int>> res = sol->printDuplicateLevels();
    cout << "[ ";
    for (auto v : res) {
        cout << "[ ";
        for (int i : v) {
            cout << i << " ";
        }
        cout << "] ";
    }
    cout << "]" << endl;
 
    return 0;
}


Java




import java.util.*;
 
// Class containing left and right
// child of the current node and key value
class Node {
    int data;
    Node left, right;
 
    // Constructor
    Node(int item) {
        data = item;
        left = right = null;
    }
}
 
class LevelInfo {
    int level;
    int length;
 
    // Constructor
    LevelInfo(int level, int length) {
        this.level = level;
        this.length = length;
    }
}
 
public class Solution {
    Node root;
    Map<Integer, List<LevelInfo>> duplicateMap = new HashMap<>();
 
    // Constructor
    Solution(Node root) {
        this.root = root;
    }
 
    // Main method to print duplicate levels
    public List<List<Integer>> printDuplicateLevels() {
        int h = height(root);
        List<List<Integer>> dupLevels = new ArrayList<>();
 
        // Initialize for the root level
        LevelInfo zeroLevelInfo = new LevelInfo(0, 0);
        duplicateMap.put(root.data, new ArrayList<>(Collections.singletonList(zeroLevelInfo)));
 
        for (int i = 1; i <= h; i++) {
            List<Integer> currentLevel = new ArrayList<>();
            getCurrentLevel(root, i, currentLevel);
            int decimalValue = getDecimalValue(currentLevel);
 
            LevelInfo currentLevelInfo = new LevelInfo(i - 1, currentLevel.size());
 
            if (duplicateMap.containsKey(decimalValue)) {
                List<LevelInfo> vec = duplicateMap.get(decimalValue);
                Optional<LevelInfo> optionalInfo = vec.stream()
                        .filter(l -> l.length == currentLevel.size())
                        .findFirst();
 
                if (optionalInfo.isPresent()) {
                    List<Integer> dupLevelCurr = new ArrayList<>(Arrays.asList(i - 1, optionalInfo.get().level));
                    dupLevels.add(dupLevelCurr);
                } else {
                    duplicateMap.get(decimalValue).add(currentLevelInfo);
                }
            } else {
                duplicateMap.put(decimalValue, new ArrayList<>(Collections.singletonList(currentLevelInfo)));
            }
        }
 
        return dupLevels;
    }
 
    // Compute the "height" of a tree
    private int height(Node root) {
        if (root == null) {
            return 0;
        } else {
            // Compute height of each subtree
            int lHeight = height(root.left);
            int rHeight = height(root.right);
 
            // Use the larger one
            return Math.max(lHeight, rHeight) + 1;
        }
    }
 
    // Get nodes at the current level
    private void getCurrentLevel(Node root, int level, List<Integer> currentLevel) {
        if (root == null) {
            return;
        }
        if (level == 1) {
            currentLevel.add(root.data);
        } else if (level > 1) {
            getCurrentLevel(root.left, level - 1, currentLevel);
            getCurrentLevel(root.right, level - 1, currentLevel);
        }
    }
 
    // Get decimal value from the binary representation
    private int getDecimalValue(List<Integer> currentLevel) {
        int decimalValue = 0;
        for (int i = 0; i < currentLevel.size(); i++) {
            decimalValue += (currentLevel.get(i) << (currentLevel.size() - 1 - i));
        }
        return decimalValue;
    }
 
    public static void main(String[] args) {
        // Create the binary tree
        Node root = new Node(1);
        root.left = new Node(0);
        root.right = new Node(1);
        root.left.left = new Node(1);
        root.left.right = new Node(0);
        root.right.left = new Node(1);
        root.left.right.left = new Node(0);
        root.right.left.right = new Node(1);
        root.left.right.left.left = new Node(1);
 
        // Print the duplicate levels
        Solution sol = new Solution(root);
        List<List<Integer>> res = sol.printDuplicateLevels();
        System.out.print("[ ");
        for (List<Integer> v : res) {
            System.out.print("[ ");
            for (int i : v) {
                System.out.print(i + " ");
            }
            System.out.print("] ");
        }
        System.out.println("]");
    }
}


Python3




# Python program to implement above approach
 
# Class containing left and right
# child of current node and key value
class Node:
    def __init__(self, item):
        self.data = item
        self.left = None
        self.right = None
 
class LevelInfo:
    def __init__(self):
        self.level = 0
        self.length = 0
 
class GFG:
    # Root of the Binary Tree
    def __init__(self):
        self.root = None
        self.duplicateMap = {}
 
    def printDuplicateLevels(self, root):
        def height(root):
            if root is None:
                return 0
            else:
                lheight = height(root.left)
                rheight = height(root.right)
                if lheight > rheight:
                    return lheight + 1
                else:
                    return rheight + 1
 
        def getCurrentLevel(root, level, currentLevelOrder):
            if root is None:
                return currentLevelOrder
            if level == 1:
                currentLevelOrder.append(root.data)
            elif level > 1:
                currentLevelOrder = getCurrentLevel(root.left, level - 1, currentLevelOrder)
                currentLevelOrder = getCurrentLevel(root.right, level - 1, currentLevelOrder)
            return currentLevelOrder
 
        h = height(root)
        dup_levels = []
        zerolevelInfo = LevelInfo()
        zerolevelInfo.level = 0
        zerolevelInfo.length = 0
        self.duplicateMap[root.data] = [zerolevelInfo]
        for i in range(1, h+1):
            currentLevel = []
            currentLevelOrder = getCurrentLevel(root, i, currentLevel)
            decimalValue = int("".join(map(str, currentLevelOrder)), 2)
            currentlevelInfo = LevelInfo()
            currentlevelInfo.level = i - 1
            currentlevelInfo.length = len(currentLevelOrder)
            if decimalValue in self.duplicateMap:
                dictData = [l for l in self.duplicateMap[decimalValue] if l.length == currentlevelInfo.length]
                if dictData:
                    dup_level_curr = [i - 1, dictData[0].level]
                    dup_levels.append(dup_level_curr)
                else:
                    self.duplicateMap[decimalValue].append(currentlevelInfo)
            else:
                self.duplicateMap[decimalValue] = [currentlevelInfo]
        return dup_levels
 
# Driver Code
if __name__ == "__main__":
    tree = GFG()
    tree.root = Node(1)
    tree.root.left = Node(0)
    tree.root.right = Node(1)
 
    tree.root.left.left = Node(1)
    tree.root.left.right = Node(0)
 
    tree.root.right.left = Node(1)
 
    tree.root.left.right.left = Node(0)
    tree.root.right.left.right = Node(1)
 
    tree.root.left.right.left.left = Node(1)
 
    # Execute and print the duplicate levels
    dup_levels = tree.printDuplicateLevels(tree.root)
 
    print("[", end=" ")
    for curr_level in dup_levels:
        print("[", end=" ")
        for dupli_level in curr_level:
            print(dupli_level, end=" ")
        print("]", end=" ")
    print("]")


C#




// C# program to implement above approach
 
using System;
using System.Collections.Generic;
using System.Linq;
 
// Class containing left and right
// child of current node and key value
public class Node {
    public int data;
    public Node left, right;
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
public class LevelInfo {
    public int level;
    public int length;
}
 
public class GFG {
 
    // Root of the Binary Tree
    public Node root;
    Dictionary<int, List<LevelInfo> > duplicateMap
        = new Dictionary<int, List<LevelInfo> >();
 
    public virtual List<List<int> >
    printDuplicateLevels(Node root)
    {
        int h = height(root);
        int i;
 
        List<List<int> > dup_levels
            = new List<List<int> >();
 
        // Initialize for the root level
        var zerolevelInfo
            = new LevelInfo() { level = 0,
                                length = 0 };
 
        duplicateMap[root.data]
            = new List<LevelInfo>() { zerolevelInfo };
 
        for (i = 1; i <= h; i++) {
            List<int> currentLevel
                = new List<int>();
            var currentLevelOrder
                = getCurrentLevel(root, i,
                                  currentLevel)
                      .ToList();
 
            int decimalValue = Convert.ToInt32(
                string.Join("", currentLevelOrder), 2);
 
            var currentlevelInfo = new LevelInfo() {
                level = i - 1, length
                               = currentLevelOrder.Count()
            };
 
            if (duplicateMap.ContainsKey(decimalValue)) {
                var dictData
                    = duplicateMap[decimalValue].Where(
                        l => l.length
                            == currentLevelOrder.Count());
                if (dictData.Any()) {
                    List<int> dup_level_curr
                        = new List<int>();
                    dup_level_curr.Add(i - 1);
                    dup_level_curr.Add(
                        dictData.Select(l => l.level)
                            .First());
                    dup_levels.Add(dup_level_curr);
                }
                else {
                    duplicateMap[decimalValue].Add(
                        currentlevelInfo);
                }
            }
            else
                duplicateMap[decimalValue]
                    = new List<LevelInfo>() {
                          currentlevelInfo
                      };
        }
 
        return dup_levels;
    }
 
    // Compute the "height" of a tree
    public virtual int height(Node root)
    {
        if (root == null) {
            return 0;
        }
        else {
 
            // Compute height of each subtree
            int lheight = height(root.left);
            int rheight = height(root.right);
 
            // Use the larger one
            if (lheight > rheight) {
                return (lheight + 1);
            }
            else {
                return (rheight + 1);
            }
        }
    }
 
    // Get nodes at the current level
    public virtual IList<int>
    getCurrentLevel(Node root, int level,
                    List<int> currentLevelOrder)
    {
        if (root == null) {
            return currentLevelOrder;
        }
        if (level == 1) {
            currentLevelOrder.Add(root.data);
        }
        else if (level > 1) {
            getCurrentLevel(root.left, level - 1,
                            currentLevelOrder);
            getCurrentLevel(root.right, level - 1,
                            currentLevelOrder);
        }
        return currentLevelOrder;
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        GFG tree = new GFG();
        tree.root = new Node(1);
        tree.root.left = new Node(0);
        tree.root.right = new Node(1);
 
        tree.root.left.left = new Node(1);
        tree.root.left.right = new Node(0);
 
        tree.root.right.left = new Node(1);
 
        tree.root.left.right.left = new Node(0);
        tree.root.right.left.right = new Node(1);
 
        tree.root.left.right.left.left = new Node(1);
 
        // Execute and print the duplicate levels
        List<List<int> > dup_levels
            = tree.printDuplicateLevels(tree.root);
 
        Console.Write("[ ");
        foreach(var curr_level in dup_levels)
        {
            Console.Write("[ ");
            foreach(var dupli_level in curr_level)
            {
                Console.Write(dupli_level + " ");
            }
            Console.Write("] ");
        }
        Console.WriteLine("]");
    }
}


Javascript




class Node {
  constructor(item) {
    this.data = item;
    this.left = null;
    this.right = null;
  }
}
 
class LevelInfo {
  constructor(level, length) {
    this.level = level;
    this.length = length;
  }
}
 
class Solution {
  constructor(root) {
    this.root = root;
    this.duplicateMap = new Map();
  }
 
  printDuplicateLevels() {
    const h = this.height(this.root);
    const dup_levels = [];
 
    // Initialize for the root level
    const zerolevelInfo = new LevelInfo(0, 0);
    this.duplicateMap.set(this.root.data, [zerolevelInfo]);
 
    for (let i = 1; i <= h; i++) {
      const currentLevel = [];
      this.getCurrentLevel(this.root, i, currentLevel);
      const decimalValue = this.getDecimalValue(currentLevel);
 
      const currentlevelInfo = new LevelInfo(i - 1, currentLevel.length);
 
      if (this.duplicateMap.has(decimalValue)) {
        const vec = this.duplicateMap.get(decimalValue);
        const it = vec.find((l) => l.length === currentLevel.length);
        if (it !== undefined) {
          const dup_level_curr = [i - 1, it.level];
          dup_levels.push(dup_level_curr);
        } else {
          this.duplicateMap.set(decimalValue, [...vec, currentlevelInfo]);
        }
      } else {
        this.duplicateMap.set(decimalValue, [currentlevelInfo]);
      }
    }
 
    return dup_levels;
  }
 
  // Compute the "height" of a binary tree
  height(root) {
    if (root === null) {
      return 0;
    } else {
      // Compute height of each sub
      const lheight = this.height(root.left);
      const rheight = this.height(root.right);
 
      // Use the larger one
      if (lheight > rheight) {
        return lheight + 1;
      } else {
        return rheight + 1;
      }
    }
  }
 
  // Get nodes at the current level
  getCurrentLevel(root, level, currentLevel) {
    if (root === null) {
      return;
    }
    if (level === 1) {
      currentLevel.push(root.data);
    } else if (level > 1) {
      this.getCurrentLevel(root.left, level - 1, currentLevel);
      this.getCurrentLevel(root.right, level - 1, currentLevel);
    }
  }
 
  getDecimalValue(currentLevel) {
    let decimalValue = 0;
    for (let i = 0; i < currentLevel.length; i++) {
      decimalValue += currentLevel[i] << (currentLevel.length - 1 - i);
    }
    return decimalValue;
  }
}
 
// create the binary tree
const root = new Node(1);
root.left = new Node(0);
root.right = new Node(1);
root.left.left = new Node(1);
root.left.right = new Node(0);
root.right.left = new Node(1);
root.left.right.left = new Node(0);
root.right.left.right = new Node(1);
root.left.right.left.left = new Node(1);
 
// print the duplicate levels
const sol = new Solution(root);
const res = sol.printDuplicateLevels();
console.log(res);
 
//This code is contributed by Akash Jha


Output

[ [ 3 1 ] [ 4 0 ] ]

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

C# code information:-

This is a C# code to find the levels in a binary tree that are duplicates of other levels. It starts by finding the height of the tree and for each level, it finds the binary representation of the values at the current level and adds them to a dictionary. If a binary representation of the current level is already in the dictionary, it checks if the length of the binary representation matches any of the previous lengths. If there is a match, it adds the current level and the corresponding level from the dictionary to a list of duplicate levels. Finally, the list of duplicate levels is returned.

Python code information:-

  • The program defines two classes: Node and LevelInfo.
  • The Node class is used to represent a node in the binary tree. It has three attributes: data to store the value of the node, and left and right to store references to its left and right child nodes, respectively.
  • The LevelInfo class is used to store the level number and length of the level order traversal of the binary tree nodes.
  • The GFG class defines the root node of the binary tree and a dictionary to store the duplicate subtrees found during the traversal of the binary tree.
  • The printDuplicateLevels method is used to print the levels of the binary tree that have duplicate subtrees.
  • The method height is used to find the height of the binary tree.
  • The method getCurrentLevel is used to get the nodes at a particular level.
  • The method printDuplicateLevels first gets the height of the binary tree. Then, it traverses each level of the binary tree and computes a decimal value for the level order traversal of the nodes. 


Last Updated : 23 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads