Given two Binary Trees we have to detect if the two trees are Isomorphic. Two trees are called isomorphic if one of them can be obtained from another by a series of flips, i.e. by swapping left and right children of a number of nodes. Any number of nodes at any level can have their children swapped.
Note: Two empty trees are isomorphic.
For example, the following two trees are isomorphic with the following sub-trees flipped: 2 and 3, NULL and 6, 7, and 8.

Approach:
To solve the question mentioned above we traverse both the trees iteratively using level order traversal and store the levels in a queue data structure. There are following two conditions at each level:
- The value of nodes has to be the same.
- The number of nodes at each level should be the same.
Check the size of the queue to match the second condition mentioned above. Store the nodes of each level of the first tree as key with a value and for the second tree, we will store all the nodes of a level in a vector. If the key is found we will decrease the value to keep track of how many nodes with the same value exists at a level. If the value becomes zero that means the first tree has only this much number of nodes, and we will remove it as a key. At the end of each level, we will iterate through the array and check whether each value exists on the map or not. There will be three conditions:
- If the key is not found then the first tree doesn’t contain a node found in the second tree at the same level.
- If the key is found but the value becomes negative then the second tree has more nodes with the same value as the first tree.
- If map size is not zero, this means there are some keys still left which means the first tree has a node that doesn’t match with any node in the second tree.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct node {
int data;
struct node* left;
struct node* right;
};
bool isIsomorphic(node* root1, node* root2)
{
if (root1 == NULL and root2 == NULL)
return true ;
else if (root1 == NULL or root2 == NULL)
return false ;
queue<node *> q1, q2;
q1.push(root1);
q2.push(root2);
int level = 0;
int size;
vector< int > v2;
unordered_map< int , int > mp;
while (!q1.empty() and !q2.empty()) {
if (q1.size() != q2.size())
return false ;
size = q1.size();
level++;
v2.clear();
mp.clear();
while (size--) {
node* temp1 = q1.front();
node* temp2 = q2.front();
q1.pop();
q2.pop();
if (mp.find(temp1->data) == mp.end())
mp[temp1->data] = 1;
else
mp[temp1->data]++;
v2.push_back(temp2->data);
if (temp1->left)
q1.push(temp1->left);
if (temp1->right)
q1.push(temp1->right);
if (temp2->left)
q2.push(temp2->left);
if (temp2->right)
q2.push(temp2->right);
}
for ( auto i : v2) {
if (mp.find(i) == mp.end())
return false ;
else {
mp[i]--;
if (mp[i] < 0)
return false ;
else if (mp[i] == 0)
mp.erase(i);
}
}
if (mp.size() != 0)
return false ;
}
return true ;
}
node* newnode( int data)
{
node* temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return (temp);
}
int main()
{
struct node* n1 = newnode(1);
n1->left = newnode(2);
n1->right = newnode(3);
n1->left->left = newnode(4);
n1->left->right = newnode(5);
n1->right->left = newnode(6);
n1->left->right->left = newnode(7);
n1->left->right->right = newnode(8);
struct node* n2 = newnode(1);
n2->left = newnode(3);
n2->right = newnode(2);
n2->right->left = newnode(4);
n2->right->right = newnode(5);
n2->left->right = newnode(6);
n2->right->right->left = newnode(8);
n2->right->right->right = newnode(7);
if (isIsomorphic(n1, n2) == true )
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
class GFG{
static class Node
{
int data;
Node left, right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
};
static boolean isIsomorphic(Node root1,
Node root2)
{
if (root1 == null &&
root2 == null )
return true ;
else if (root1 == null ||
root2 == null )
return false ;
Queue<Node> q1 =
new LinkedList<>(),
q2 = new LinkedList<>();
q1.add(root1);
q2.add(root2);
int level = 0 ;
int size;
ArrayList<Integer> v2 =
new ArrayList<>();
HashMap<Integer,
Integer> mp = new HashMap<>();
while (!q1.isEmpty() &&
!q2.isEmpty())
{
if (q1.size() != q2.size())
return false ;
size = q1.size();
level++;
v2.clear();
mp.clear();
while (size-- > 0 )
{
Node temp1 = q1.poll();
Node temp2 = q2.poll();
if (!mp.containsKey(temp1.data))
mp.put(temp1.data, 1 );
else
mp.put(temp1.data,
mp.get(temp1.data) + 1 );
v2.add(temp2.data);
if (temp1.left != null )
q1.add(temp1.left);
if (temp1.right != null )
q1.add(temp1.right);
if (temp2.left != null )
q2.add(temp2.left);
if (temp2.right != null )
q2.add(temp2.right);
}
for (Integer i : v2)
{
if (!mp.containsKey(i))
return false ;
else
{
mp.put(i, mp.get(i) - 1 );
if (mp.get(i) < 0 )
return false ;
else if (mp.get(i) == 0 )
mp.remove(i);
}
}
if (mp.size() != 0 )
return false ;
}
return true ;
}
public static void main(String[] args)
{
Node n1 = new Node( 1 );
n1.left = new Node( 2 );
n1.right = new Node( 3 );
n1.left.left = new Node( 4 );
n1.left.right = new Node( 5 );
n1.right.left = new Node( 6 );
n1.left.right.left = new Node( 7 );
n1.left.right.right = new Node( 8 );
Node n2 = new Node( 1 );
n2.left = new Node( 3 );
n2.right = new Node( 2 );
n2.right.left = new Node( 4 );
n2.right.right = new Node( 5 );
n2.left.right = new Node( 6 );
n2.right.right.left = new Node( 8 );
n2.right.right.right = new Node( 7 );
if (isIsomorphic(n1, n2))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
from collections import deque
class node:
def __init__( self , x):
self .data = x
self .left = None
self .right = None
def isIsomorphic(root1, root2):
if (root1 = = None and root2 = = None ):
return True
elif (root1 = = None or root2 = = None ):
return False
q1 = deque()
q2 = deque()
q1.append(root1)
q2.append(root2)
level = 0
size = 0
v1 = []
m2 = {}
while ( len (q1) > 0 and len (q2) > 0 ):
if ( len (q1) ! = len (q2)):
return False
size = len (q1)
level + = 1
v2 = []
mp = {}
while (size):
temp1 = q1.popleft()
temp2 = q2.popleft()
mp[temp1.data] = mp.get(temp1.data, 0 ) + 1
v2.append(temp2.data)
if (temp1.left):
q1.append(temp1.left)
if (temp1.right):
q1.append(temp1.right)
if (temp2.left):
q2.append(temp2.left)
if (temp2.right):
q2.append(temp2.right)
v1 = v2
m2 = mp
size - = 1
for i in v1:
if i in m2:
return True
else :
m2[i] - = 1
if (m2[i] < 0 ):
return False
elif (m2[i] = = 0 ):
del m2[i]
if ( len (m2) = = 0 ):
return False
return True
if __name__ = = '__main__' :
n1 = node( 1 )
n1.left = node( 2 )
n1.right = node( 3 )
n1.left.left = node( 4 )
n1.left.right = node( 5 )
n1.right.left = node( 6 )
n1.left.right.left = node( 7 )
n1.left.right.right = node( 8 )
n2 = node( 1 )
n2.left = node( 3 )
n2.right = node( 2 )
n2.right.left = node( 4 )
n2.right.right = node( 5 )
n2.left.right = node( 6 )
n2.right.right.left = node( 8 )
n2.right.right.right = node( 7 )
if (isIsomorphic(n1, n2) = = True ):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
class Node
{
public int data;
public Node left, right;
public Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
};
static bool isIsomorphic(Node root1,
Node root2)
{
if (root1 == null &&
root2 == null )
return true ;
else if (root1 == null ||
root2 == null )
return false ;
Queue q1 = new Queue();
Queue q2 = new Queue();
q1.Enqueue(root1);
q2.Enqueue(root2);
int level = 0;
int size;
ArrayList v2 = new ArrayList();
Dictionary< int , int > mp = new Dictionary< int , int >();
while (q1.Count != 0 && q2.Count != 0)
{
if (q1.Count != q2.Count)
return false ;
size = q1.Count;
level++;
v2.Clear();
mp.Clear();
while (size-- > 0)
{
Node temp1 = (Node)q1.Dequeue();
Node temp2 = (Node)q2.Dequeue();
if (!mp.ContainsKey(temp1.data))
mp[temp1.data] = 1;
else
mp[temp1.data]++;
v2.Add(temp2.data);
if (temp1.left != null )
q1.Enqueue(temp1.left);
if (temp1.right != null )
q1.Enqueue(temp1.right);
if (temp2.left != null )
q2.Enqueue(temp2.left);
if (temp2.right != null )
q2.Enqueue(temp2.right);
}
foreach ( int i in v2)
{
if (!mp.ContainsKey(i))
return false ;
else
{
mp[i]--;
if (mp[i] < 0)
return false ;
else if (mp[i] == 0)
mp.Remove(i);
}
}
if (mp.Count != 0)
return false ;
}
return true ;
}
public static void Main( string [] args)
{
Node n1 = new Node(1);
n1.left = new Node(2);
n1.right = new Node(3);
n1.left.left = new Node(4);
n1.left.right = new Node(5);
n1.right.left = new Node(6);
n1.left.right.left = new Node(7);
n1.left.right.right = new Node(8);
Node n2 = new Node(1);
n2.left = new Node(3);
n2.right = new Node(2);
n2.right.left = new Node(4);
n2.right.right = new Node(5);
n2.left.right = new Node(6);
n2.right.right.left = new Node(8);
n2.right.right.right = new Node(7);
if (isIsomorphic(n1, n2))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
}
|
Javascript
<script>
class Node
{
constructor(key)
{
this .data = key;
this .left = this .right = null ;
}
}
function isIsomorphic(root1, root2)
{
if (root1 == null &&
root2 == null )
return true ;
else if (root1 == null ||
root2 == null )
return false ;
let q1 =[],
q2 = [];
q1.push(root1);
q2.push(root2);
let level = 0;
let size;
let v2 = [];
let mp = new Map();
while (q1.length != 0 &&
q2.length != 0)
{
if (q1.length != q2.length)
return false ;
size = q1.length;
level++;
v2 = [];
while (size-- > 0)
{
let temp1 = q1.shift();
let temp2 = q2.shift();
if (!mp.has(temp1.data))
mp.set(temp1.data, 1);
else
mp.set(temp1.data,
mp.get(temp1.data) + 1);
v2.push(temp2.data);
if (temp1.left != null )
q1.push(temp1.left);
if (temp1.right != null )
q1.push(temp1.right);
if (temp2.left != null )
q2.push(temp2.left);
if (temp2.right != null )
q2.push(temp2.right);
}
for (let i = 0; i < v2.length; i++)
{
if (!mp.has(v2[i]))
return false ;
else
{
mp.set(v2[i], mp.get(v2[i]) - 1);
if (mp.get(v2[i]) < 0)
return false ;
else if (mp.get(v2[i]) == 0)
mp. delete (v2[i]);
}
}
if (mp.size != 0)
return false ;
}
return true ;
}
let n1 = new Node(1);
n1.left = new Node(2);
n1.right = new Node(3);
n1.left.left = new Node(4);
n1.left.right = new Node(5);
n1.right.left = new Node(6);
n1.left.right.left = new Node(7);
n1.left.right.right = new Node(8);
let n2 = new Node(1);
n2.left = new Node(3);
n2.right = new Node(2);
n2.right.left = new Node(4);
n2.right.right = new Node(5);
n2.left.right = new Node(6);
n2.right.right.left = new Node(8);
n2.right.right.right = new Node(7);
if (isIsomorphic(n1, n2))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
19 Aug, 2021
Like Article
Save Article