Find all duplicate levels of given Binary Tree
Last Updated :
23 Dec, 2023
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.
Similar Reads
Duplicate subtree in Binary Tree | SET 2 Given a binary tree, the task is to check whether the binary tree contains a duplicate sub-tree of size two or more. Input: A / \ B C / \ \ D E B / \ D E Output: Yes B / \ D E is the duplicate sub-tree. Input: A / \ B C / \ D E Output: No Approach: A DFS based approach has been discussed here. A que
8 min read
Nodes at Kth level without duplicates in a Binary Tree Given a binary tree with N nodes and an integer K, the task is to print nodes of the Kth level of a binary tree without duplicates. Examples: Input: 60 --- Level 0 / \ 50 30 --- Level 1 / \ / 80 10 40 --- Level 2 K = 1 Output: 30 50 Input: 50 --- Level 0 / \ 60 70 --- Level 1 / \ / \ 90 40 40 20 ---
11 min read
Find maximum count of duplicate nodes in a Binary Search Tree Given a Binary Search Tree (BST) with duplicates, find the node (the most frequently occurred element) in the given BST. If the BST contains two or more such nodes, print any of them. Note: We cannot use any extra space. (Assume that the implicit stack space incurred due to recursion does not count)
9 min read
Find Minimum Depth of a Binary Tree Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. For example, minimum depth of below Binary Tree is 2. Note that the path must end on a leaf node. For example, the minimum depth of below Bi
15 min read
Find the largest Complete Subtree in a given Binary Tree Given a Binary Tree, the task is to find the size and also the inorder traversal of the largest Complete sub-tree in the given Binary Tree. Complete Binary Tree - A Binary tree is a Complete Binary Tree if all levels are filled except possibly the last level and the last level has all keys as left a
13 min read
How to handle duplicates in Binary Search Tree? In a Binary Search Tree (BST), all keys in the left subtree of a key must be smaller and all keys in the right subtree must be greater. So a Binary Search Tree by definition has distinct keys. How can duplicates be allowed where every insertion inserts one more key with a value and every deletion de
15+ min read
Diameter of a Binary Indexed Tree with N nodes Given a Binary Indexed Tree with N nodes except root node 0 (Numbered from 1 to N), Find its diameter. Binary Indexed Tree is a tree where parent of a node number X = X - (X & (X - 1)) i.e. last bit is unset in X. The diameter of a tree is the longest simple path between any two leaves. Examples
7 min read
Find All Duplicate Subtrees Given a binary tree, the task is to find all duplicate subtrees. For each duplicate subtree, we only need to return the root node of any one of them. Two trees are duplicates if they have the same structure with the same node values.Example: Input : Binary tree 1 / \ 2 3 / / \ 4 2 4 / 4Output : 2 /
15+ min read
Level of a Node in Binary Tree Given a Binary Tree and a key, the task is to find the level of key in the Binary Tree.Examples:Input : key = 4Output: 3Explanation: The level of the key in above binary tree is 3.Input : key = 10Output: -1Explanation: Key is not present in the above Binary tree.Table of Content[Expected Approach -
12 min read
Odd level sum of given Binary Tree Given a binary tree, write a function that takes the root node and updates the original tree in such a way every node that is present at an odd level gets updated as the sum of the node's value and its grandparent's value. Examples: Input: Consider a binary tree having values {3, 2, 5, 1, 4, NULL, 7
8 min read