Given two binary trees, a and b, check whether the two trees are mirror images of each other. Two binary trees are mirror images if:
Their root nodes have the same value.
The left subtree of the first tree is the mirror of the right subtree of the second tree.
The right subtree of the first tree is the mirror of the left subtree of the second tree.
Example:
Input: a[] = [1, 3, 2, N, N, 5, 4], b[] = [1, 2, 3, 4, 5, N, N]
Output: true Explanation: Both trees have the same values and opposite subtree structures, so they are mirror images.
Input: a = [1, 2, 3], b = [1, 2, 4]
Output: false Explanation: The root values are the same, but the corresponding nodes 3 and 4 have different values. Therefore, the two trees are not mirror images of each other.
Two binary trees are mirror images if their corresponding nodes have the same values and their left and right subtrees appear in opposite positions.
Suppose we are comparing nodes a and b. There are three cases:
If both nodes are NULL, there is nothing left to compare, so they are mirrors.
If only one node is NULL, the tree structures are different, so they are not mirrors.
If both nodes exist, their values must be equal. If the values are different, the trees are not mirrors. Otherwise, recursively compare their opposite subtrees.
For every pair of nodes:
Compare a->left with b->right.
Compare a->right with b->left.
The trees are mirrors only if both opposite subtree comparisons return true.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};boolareMirror(Node*a,Node*b){// If both roots are NULL, they are mirrorsif(a==nullptr&&b==nullptr)returntrue;// If only one root is NULL, they are not mirrorsif(a==nullptr||b==nullptr)returnfalse;// If values are different, they are not mirrorsif(a->data!=b->data)returnfalse;// Compare opposite subtreesboolleft=areMirror(a->left,b->right);boolright=areMirror(a->right,b->left);// Both subtree comparisons must be truereturnleft&&right;}intmain(){// Representation of input binary tree 1// 1// / \ // 3 2// / \ // 5 4Node*a=newNode(1);a->left=newNode(3);a->right=newNode(2);a->right->left=newNode(5);a->right->right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \ // 2 3// / \ // 4 5Node*b=newNode(1);b->left=newNode(2);b->right=newNode(3);b->left->left=newNode(4);b->left->right=newNode(5);if(areMirror(a,b))cout<<"true\n";elsecout<<"false\n";return0;}
Java
classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGFG{staticbooleanareMirror(Nodea,Nodeb){// If both roots are NULL, they are mirrorsif(a==null&&b==null)returntrue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreesbooleanleft=areMirror(a.left,b.right);booleanright=areMirror(a.right,b.left);// Both subtree comparisons must be truereturnleft&&right;}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))System.out.println("true");elseSystem.out.println("false");}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefareMirror(a,b):# If both roots are NULL, they are mirrorsifaisNoneandbisNone:returnTrue# If only one root is NULL, they are not mirrorsifaisNoneorbisNone:returnFalse# If values are different, they are not mirrorsifa.data!=b.data:returnFalse# Compare opposite subtreesleft=areMirror(a.left,b.right)right=areMirror(a.right,b.left)# Both subtree comparisons must be truereturnleftandrightif__name__=="__main__":# Representation of input binary tree 1# 1# / \# 3 2# / \# 5 4a=Node(1)a.left=Node(3)a.right=Node(2)a.right.left=Node(5)a.right.right=Node(4)# Representation of input binary tree 2 (mirror)# 1# / \# 2 3# / \# 4 5b=Node(1)b.left=Node(2)b.right=Node(3)b.left.left=Node(4)b.left.right=Node(5)ifareMirror(a,b):print("true")else:print("false")
C#
usingSystem;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{staticboolareMirror(Nodea,Nodeb){// If both roots are NULL, they are mirrorsif(a==null&&b==null)returntrue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreesboolleft=areMirror(a.left,b.right);boolright=areMirror(a.right,b.left);// Both subtree comparisons must be truereturnleft&&right;}staticvoidMain(){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionareMirror(a,b){// If both roots are NULL, they are mirrorsif(a===null&&b===null)returntrue;// If only one root is NULL, they are not mirrorsif(a===null||b===null)returnfalse;// If values are different, they are not mirrorsif(a.data!==b.data)returnfalse;// Compare opposite subtreesletleft=areMirror(a.left,b.right);letright=areMirror(a.right,b.left);// Both subtree comparisons must be truereturnleft&&right;}// Driver code// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4leta=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5letb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))console.log("true");elseconsole.log("false");
Output
true
Iterative Approach Using Queue - O(n) Time and O(n) Space
The idea is to compare the two trees using a queue instead of recursion. For every pair of nodes, we compare their values and then add their opposite children to the queue.
For two nodes a and b:
If both are NULL, continue.
If only one is NULL, the trees are not mirrors.
If their values are different, the trees are not mirrors.
Otherwise, add the following pairs to the queue:
a->left with b->right
a->right with b->left
Continue until all corresponding pairs are checked. If every pair satisfies the mirror condition, return true.
C++
#include<iostream>#include<queue>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};boolareMirror(Node*a,Node*b){queue<Node*>q;q.push(a);q.push(b);while(!q.empty()){a=q.front();q.pop();b=q.front();q.pop();// If both roots are NULL, they are mirrorsif(a==nullptr&&b==nullptr)continue;// If only one root is NULL, they are not mirrorsif(a==nullptr||b==nullptr)returnfalse;// If values are different, they are not mirrorsif(a->data!=b->data)returnfalse;// Compare opposite subtreesq.push(a->left);q.push(b->right);q.push(a->right);q.push(b->left);}// All subtree comparisons are truereturntrue;}intmain(){// Representation of input binary tree 1// 1// / \ // 3 2// / \ // 5 4Node*a=newNode(1);a->left=newNode(3);a->right=newNode(2);a->right->left=newNode(5);a->right->right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \ // 2 3// / \ // 4 5Node*b=newNode(1);b->left=newNode(2);b->right=newNode(3);b->left->left=newNode(4);b->left->right=newNode(5);if(areMirror(a,b))cout<<"true\n";elsecout<<"false\n";return0;}
Java
importjava.util.LinkedList;importjava.util.Queue;classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGFG{staticbooleanareMirror(Nodea,Nodeb){Queue<Node>q=newLinkedList<>();q.add(a);q.add(b);while(!q.isEmpty()){a=q.remove();b=q.remove();// If both roots are NULL, they are mirrorsif(a==null&&b==null)continue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreesq.add(a.left);q.add(b.right);q.add(a.right);q.add(b.left);}// All subtree comparisons are truereturntrue;}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))System.out.println("true");elseSystem.out.println("false");}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefareMirror(a,b):q=deque()q.append(a)q.append(b)whileq:a=q.popleft()b=q.popleft()# If both roots are NULL, they are mirrorsifaisNoneandbisNone:continue# If only one root is NULL, they are not mirrorsifaisNoneorbisNone:returnFalse# If values are different, they are not mirrorsifa.data!=b.data:returnFalse# Compare opposite subtreesq.append(a.left)q.append(b.right)q.append(a.right)q.append(b.left)# All subtree comparisons are truereturnTrueif__name__=="__main__":# Representation of input binary tree 1# 1# / \# 3 2# / \# 5 4a=Node(1)a.left=Node(3)a.right=Node(2)a.right.left=Node(5)a.right.right=Node(4)# Representation of input binary tree 2 (mirror)# 1# / \# 2 3# / \# 4 5b=Node(1)b.left=Node(2)b.right=Node(3)b.left.left=Node(4)b.left.right=Node(5)ifareMirror(a,b):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{publicstaticboolareMirror(Nodea,Nodeb){Queue<Node>q=newQueue<Node>();q.Enqueue(a);q.Enqueue(b);while(q.Count>0){a=q.Dequeue();b=q.Dequeue();// If both roots are NULL, they are mirrorsif(a==null&&b==null)continue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreesq.Enqueue(a.left);q.Enqueue(b.right);q.Enqueue(a.right);q.Enqueue(b.left);}// All subtree comparisons are truereturntrue;}publicstaticvoidMain(){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionareMirror(a,b){letq=[];q.push(a);q.push(b);letfront=0;while(front<q.length){a=q[front++];b=q[front++];// If both roots are NULL, they are mirrorsif(a===null&&b===null)continue;// If only one root is NULL, they are not mirrorsif(a===null||b===null)returnfalse;// If values are different, they are not mirrorsif(a.data!==b.data)returnfalse;// Compare opposite subtreesq.push(a.left);q.push(b.right);q.push(a.right);q.push(b.left);}// All subtree comparisons are truereturntrue;}// Driver code// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4leta=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5letb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))console.log("true");elseconsole.log("false");
Output
true
Iterative Approach Using Two Stacks - O(n) Time and O(n) Auxiliary Space
The idea is to use two stacks to compare the nodes of both trees without recursion. One stack stores nodes from the first tree, and the other stores nodes from the second tree.
For every pair of nodes a and b:
If both nodes are NULL, continue.
If only one node is NULL, return false.
If their values are different, return false.
Push a->left and b->right into their respective stacks.
Push a->right and b->left into their respective stacks.
This ensures that the left subtree of one tree is always compared with the right subtree of the other tree. If their values are different, return false.
C++
#include<iostream>#include<stack>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};boolareMirror(Node*a,Node*b){stack<Node*>s1,s2;s1.push(a);s2.push(b);while(!s1.empty()&&!s2.empty()){a=s1.top();s1.pop();b=s2.top();s2.pop();// If both roots are NULL, they are mirrorsif(a==nullptr&&b==nullptr)continue;// If only one root is NULL, they are not mirrorsif(a==nullptr||b==nullptr)returnfalse;// If values are different, they are not mirrorsif(a->data!=b->data)returnfalse;// Compare opposite subtreess1.push(a->left);s2.push(b->right);s1.push(a->right);s2.push(b->left);}// All subtree comparisons are truereturns1.empty()&&s2.empty();}intmain(){// Representation of input binary tree 1// 1// / \ // 3 2// / \ // 5 4Node*a=newNode(1);a->left=newNode(3);a->right=newNode(2);a->right->left=newNode(5);a->right->right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \ // 2 3// / \ // 4 5Node*b=newNode(1);b->left=newNode(2);b->right=newNode(3);b->left->left=newNode(4);b->left->right=newNode(5);if(areMirror(a,b))cout<<"true\n";elsecout<<"false\n";return0;}
Java
importjava.util.Stack;classNode{intdata;Nodeleft;Noderight;Node(intx){data=x;left=right=null;}}classGFG{publicstaticbooleanareMirror(Nodea,Nodeb){Stack<Node>s1=newStack<>();Stack<Node>s2=newStack<>();s1.push(a);s2.push(b);while(!s1.empty()&&!s2.empty()){a=s1.pop();b=s2.pop();// If both roots are NULL, they are mirrorsif(a==null&&b==null)continue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreess1.push(a.left);s2.push(b.right);s1.push(a.right);s2.push(b.left);}// All subtree comparisons are truereturns1.empty()&&s2.empty();}publicstaticvoidmain(String[]args){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))System.out.println("true");elseSystem.out.println("false");}}
Python
classNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefareMirror(a,b):s1=[]s2=[]s1.append(a)s2.append(b)whiles1ands2:a=s1.pop()b=s2.pop()# If both roots are NULL, they are mirrorsifaisNoneandbisNone:continue# If only one root is NULL, they are not mirrorsifaisNoneorbisNone:returnFalse# If values are different, they are not mirrorsifa.data!=b.data:returnFalse# Compare opposite subtreess1.append(a.left)s2.append(b.right)s1.append(a.right)s2.append(b.left)# All subtree comparisons are truereturnnots1andnots2if__name__=="__main__":# Representation of input binary tree 1# 1# / \# 3 2# / \# 5 4a=Node(1)a.left=Node(3)a.right=Node(2)a.right.left=Node(5)a.right.right=Node(4)# Representation of input binary tree 2 (mirror)# 1# / \# 2 3# / \# 4 5b=Node(1)b.left=Node(2)b.right=Node(3)b.left.left=Node(4)b.left.right=Node(5)ifareMirror(a,b):print("true")else:print("false")
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{staticboolareMirror(Nodea,Nodeb){Stack<Node>s1=newStack<Node>();Stack<Node>s2=newStack<Node>();s1.Push(a);s2.Push(b);while(s1.Count>0&&s2.Count>0){a=s1.Pop();b=s2.Pop();// If both roots are NULL, they are mirrorsif(a==null&&b==null)continue;// If only one root is NULL, they are not mirrorsif(a==null||b==null)returnfalse;// If values are different, they are not mirrorsif(a.data!=b.data)returnfalse;// Compare opposite subtreess1.Push(a.left);s2.Push(b.right);s1.Push(a.right);s2.Push(b.left);}// All subtree comparisons are truereturns1.Count==0&&s2.Count==0;}staticvoidMain(){// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4Nodea=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5Nodeb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))Console.WriteLine("true");elseConsole.WriteLine("false");}}
JavaScript
classNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionareMirror(a,b){lets1=[];lets2=[];s1.push(a);s2.push(b);while(s1.length>0&&s2.length>0){a=s1.pop();b=s2.pop();// If both roots are NULL, they are mirrorsif(a===null&&b===null)continue;// If only one root is NULL, they are not mirrorsif(a===null||b===null)returnfalse;// If values are different, they are not mirrorsif(a.data!==b.data)returnfalse;// Compare opposite subtreess1.push(a.left);s2.push(b.right);s1.push(a.right);s2.push(b.left);}// All subtree comparisons are truereturns1.length===0&&s2.length===0;}// Driver code// Representation of input binary tree 1// 1// / \// 3 2// / \// 5 4leta=newNode(1);a.left=newNode(3);a.right=newNode(2);a.right.left=newNode(5);a.right.right=newNode(4);// Representation of input binary tree 2 (mirror)// 1// / \// 2 3// / \// 4 5letb=newNode(1);b.left=newNode(2);b.right=newNode(3);b.left.left=newNode(4);b.left.right=newNode(5);if(areMirror(a,b))console.log("true");elseconsole.log("false");