Given two Binary Trees, the task is to check whether they are isomorphic or not. Two trees are called isomorphic if one of them can be obtained from the other by a series of flips, i.e. by swapping left and right children of several nodes. Any number of nodes at any level can have their children swapped.
Note:
If two trees are the same (same structure and node values), they are isomorphic.
Two empty trees are isomorphic.
If the root node values of both trees differ, they are not isomorphic.
Examples:
Input:
Output: True Explanation: The above two trees are isomorphic with following sub-trees flipped: 2 and 3, NULL and 6, 7 and 8.
[Expected Approach - 1] Using Recursion - O(n) Time and O(n) Space
The idea is to traverse both trees recursively, comparing the nodes n1 and n2. Their data must be the same, and their subtrees must either be identical or mirror images (flipped). This ensures that the trees are structurally isomorphic.
Follow the steps to solve the problem:
Let the current internal nodes of the two trees be n1 and n2. For the subtrees rooted at n1 and n2 to be isomorphic, the following conditions must hold:
The data of n1 and n2 must be the same.
One of the following two conditions must be true for the children of n1 and n2:
The left child of n1 is isomorphic to the left child of n2, and the right child of n1 is isomorphic to the right child of n2.
The left child of n1 is isomorphic to the right child of n2, and the right child of n1 is isomorphic to the left child of n2.
This ensures that the trees are either structurally identical or have been "flipped" at some levels while still being isomorphic.
Below is the implementation of the above approach:
C++
// C++ code to check if two trees are // isomorphic using recursion#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*left,*right;Node(intx){data=x;left=right=nullptr;}};// Function to check if two trees are isomorphicboolisIsomorphic(Node*root1,Node*root2){// Both roots are NULL, trees are isomorphic// by definitionif(root1==nullptr&&root2==nullptr){returntrue;}// Exactly one of the root1 and root2 is NULL, // trees not isomorphicif(root1==nullptr||root2==nullptr){returnfalse;}// If the data doesn't match, trees // are not isomorphicif(root1->data!=root2->data){returnfalse;}// Check if the trees are isomorphic by // considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1->left,root2->left)&&isIsomorphic(root1->right,root2->right))||(isIsomorphic(root1->left,root2->right)&&isIsomorphic(root1->right,root2->left));}intmain(){// Representation of input binary tree 1// 1// / \ // 2 3// / \ // 4 5// / \ // 7 8Node*root1=newNode(1);root1->left=newNode(2);root1->right=newNode(3);root1->left->left=newNode(4);root1->left->right=newNode(5);root1->left->right->left=newNode(7);root1->left->right->right=newNode(8);// Representation of input binary tree 2// 1// / \ // 3 2// / / \ // 6 4 5// / \ // 8 7Node*root2=newNode(1);root2->left=newNode(3);root2->right=newNode(2);root2->left->left=newNode(6);root2->right->left=newNode(4);root2->right->right=newNode(5);root2->right->right->left=newNode(8);root2->right->right->right=newNode(7);if(isIsomorphic(root1,root2)){cout<<"True\n";}else{cout<<"False\n";}return0;}
Java
// Java code to check if two trees are // isomorphic using recursionimportjava.util.*;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGfG{// Function to check if two trees are isomorphicstaticbooleanisIsomorphic(Noderoot1,Noderoot2){// Both roots are NULL, trees are // isomorphic by definitionif(root1==null&&root2==null){returntrue;}// Exactly one of the root1 and root2 is NULL,// trees not isomorphicif(root1==null||root2==null){returnfalse;}// If the data doesn't match, trees are not isomorphicif(root1.data!=root2.data){returnfalse;}// Check if the trees are isomorphic by // considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \// 4 5// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// / / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.left=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){System.out.println("True");}else{System.out.println("False");}}}
Python
# Python code to check if two trees are # isomorphic using recursionclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None# Function to check if two trees are isomorphicdefisIsomorphic(root1,root2):# Both roots are None, trees are # isomorphic by definitionifroot1isNoneandroot2isNone:returnTrue# Exactly one of the root1 and root2 is None,# trees not isomorphicifroot1isNoneorroot2isNone:returnFalse# If the data doesn't match, trees are not isomorphicifroot1.data!=root2.data:returnFalse# Check if the trees are isomorphic by considering # the two cases:# Case 1: The subtrees have not been flipped# Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)andisIsomorphic(root1.right,root2.right))or \
(isIsomorphic(root1.left,root2.right)andisIsomorphic(root1.right,root2.left))if__name__=="__main__":# Representation of input binary tree 1# 1# / \# 2 3# / \# 4 5# / \# 7 8root1=Node(1)root1.left=Node(2)root1.right=Node(3)root1.left.left=Node(4)root1.left.right=Node(5)root1.left.right.left=Node(7)root1.left.right.right=Node(8)# Representation of input binary tree 2# 1# / \# 3 2# / / \# 6 4 5# / \# 8 7root2=Node(1)root2.left=Node(3)root2.right=Node(2)root2.left.left=Node(6)root2.right.left=Node(4)root2.right.right=Node(5)root2.right.right.left=Node(8)root2.right.right.right=Node(7)ifisIsomorphic(root1,root2):print("True")else:print("False")
C#
// C# code to check if two trees are // isomorphic using recursionusingSystem;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=right=null;}}classGfG{// Function to check if two trees are isomorphicstaticboolisIsomorphic(Noderoot1,Noderoot2){// Both roots are null, trees are // isomorphic by definitionif(root1==null&&root2==null){returntrue;}// Exactly one of the root1 and root2 is null, // trees not isomorphicif(root1==null||root2==null){returnfalse;}// If the data doesn't match, trees are not isomorphicif(root1.data!=root2.data){returnfalse;}// Check if the trees are isomorphic by // considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}staticvoidMain(string[]args){// Representation of input binary tree 1// 1// / \// 2 3// / \// 4 5// / \// 7 8Noderoot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// / / \// 6 4 5// / \// 8 7Noderoot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.left=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){Console.WriteLine("True");}else{Console.WriteLine("False");}}}
JavaScript
// Javascript code to check if two trees are // isomorphic using recursionclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Function to check if two trees are isomorphicfunctionisIsomorphic(root1,root2){// Both roots are null, trees are isomorphic// by definitionif(root1===null&&root2===null){returntrue;}// Exactly one of the root1 and root2 is null,// trees not isomorphicif(root1===null||root2===null){returnfalse;}// If the data doesn't match, trees are not isomorphicif(root1.data!==root2.data){returnfalse;}// Check if the trees are isomorphic by // considering the two cases:// Case 1: The subtrees have not been flipped// Case 2: The subtrees have been flippedreturn(isIsomorphic(root1.left,root2.left)&&isIsomorphic(root1.right,root2.right))||(isIsomorphic(root1.left,root2.right)&&isIsomorphic(root1.right,root2.left));}// Representation of input binary tree 1// 1// / \// 2 3// / \// 4 5// / \// 7 8constroot1=newNode(1);root1.left=newNode(2);root1.right=newNode(3);root1.left.left=newNode(4);root1.left.right=newNode(5);root1.left.right.left=newNode(7);root1.left.right.right=newNode(8);// Representation of input binary tree 2// 1// / \// 3 2// / / \// 6 4 5// / \// 8 7constroot2=newNode(1);root2.left=newNode(3);root2.right=newNode(2);root2.left.left=newNode(6);root2.right.left=newNode(4);root2.right.right=newNode(5);root2.right.right.left=newNode(8);root2.right.right.right=newNode(7);if(isIsomorphic(root1,root2)){console.log("True");}else{console.log("False");}
Output
False
Time Complexity:O(n), because each node in both trees is visited once during the isomorphism check, where n is the total number of nodes in the trees. Auxiliary Space:O(h), due to the recursion stack, where h is the height of the trees; in the worst case, this can be O(n) for skewed trees.
[Expected Approach - 2] Using Iteration - O(n) Time and O(n) Space
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.