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 0Input: 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:
#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;
} |
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( "]" );
}
} |
# 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# 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( "]" );
}
} |
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 |
[ [ 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.