Given two n-ary trees, check whether they are mirror images of each other.  Given e edges, and two arrays t1[] and t2[] representing the edges of both trees. Each pair (u, v) in the arrays represents an edge from node u to node v.
Note: Both input trees are valid trees. Hence, if v is the number of nodes, then e = v-1. The nodes are numbered from 1 to e + 1 (or v).
Examples:Â
Input: e = 2, t1[] = [1, 2, 1, 3], t2[] = [1, 3, 1, 2] Output: true Explanation: Given t1 and t2 are:
As we can clearly see, the second tree is mirror image of the first.
Input: e = 2, t1[] = [1, 2, 1, 3], t2[] = [1, 2, 1, 3] Output: false Explanation: Given t1 and t2 are:
As we can clearly see, the second tree isn't mirror image of the first.
[Naive Approach] Using Stack + Queue - O(e ^ 2) Time and O(e) Space
The idea is to traverse the first tree using a stack (DFS) and the second tree using a queue (BFS) while maintaining reverse ordering.
For every step, the nodes removed from both structures must be the same.
Before processing the next level, temporarily store the remaining queue elements while adding the children of the second tree.
If all corresponding nodes match and both traversals finish together, the trees are mirror images.
Build adjacency lists for both trees from the edge arrays.
Use a stack for the first tree and a queue for the second tree, starting from root 1.
Pop/dequeue corresponding nodes and ensure their values match.
Push first-tree children into the stack and reorder the second-tree queue while adding its children.
If all corresponding nodes match and both structures become empty together, return true; otherwise, return false.
C++
#include<bits/stdc++.h>usingnamespacestd;boolcheckMirrorTree(inte,vector<int>&t1,vector<int>&t2){intn=e+1;// Store adjacency lists of both trees.vector<vector<int>>g1(n+1),g2(n+1);// Store edges of the first tree.for(inti=0;i<2*e;i+=2){g1[t1[i]].push_back(t1[i+1]);}// Store edges of the second tree.for(inti=0;i<2*e;i+=2){g2[t2[i]].push_back(t2[i+1]);}stack<int>st;queue<int>q;// Start traversal from the root.st.push(1);q.push(1);while(!st.empty()&&!q.empty()){inta=st.top();st.pop();intb=q.front();q.pop();// Corresponding nodes must be the same.if(a!=b)returnfalse;// Push children of the first tree into the stack.for(intchild:g1[a])st.push(child);// Store the remaining queue elements temporarily.vector<int>temp;while(!q.empty()){temp.push_back(q.front());q.pop();}// Push children of the second tree into the queue.for(intchild:g2[b])q.push(child);// Restore the previous queue elements.for(intnode:temp)q.push(node);}// Both traversals must finish together.returnst.empty()&&q.empty();}intmain(){inte=2;vector<int>t1={1,2,1,3};vector<int>t2={1,3,1,2};cout<<(checkMirrorTree(e,t1,t2)?"true":"false")<<endl;return0;}
Java
importjava.util.*;classGFG{staticbooleancheckMirrorTree(inte,int[]t1,int[]t2){intn=e+1;// Store adjacency lists of both trees.ArrayList<Integer>[]g1=newArrayList[n+1];ArrayList<Integer>[]g2=newArrayList[n+1];for(inti=0;i<=n;i++){g1[i]=newArrayList<>();g2[i]=newArrayList<>();}// Store edges of the first tree.for(inti=0;i<2*e;i+=2){g1[t1[i]].add(t1[i+1]);}// Store edges of the second tree.for(inti=0;i<2*e;i+=2){g2[t2[i]].add(t2[i+1]);}Stack<Integer>st=newStack<>();Queue<Integer>q=newLinkedList<>();// Start traversal from the root.st.push(1);q.add(1);while(!st.empty()&&!q.isEmpty()){inta=st.pop();intb=q.poll();// Corresponding nodes must be the same.if(a!=b)returnfalse;// Push children of the first tree into the// stack.for(intchild:g1[a])st.push(child);// Store the remaining queue elements// temporarily.ArrayList<Integer>temp=newArrayList<>();while(!q.isEmpty())temp.add(q.poll());// Push children of the second tree into the// queue.for(intchild:g2[b])q.add(child);// Restore the previous queue elements.for(intnode:temp)q.add(node);}// Both traversals must finish together.returnst.isEmpty()&&q.isEmpty();}publicstaticvoidmain(String[]args){inte=2;int[]t1={1,2,1,3};int[]t2={1,3,1,2};System.out.println(checkMirrorTree(e,t1,t2)?"true":"false");}}
Python
fromcollectionsimportdequedefcheckMirrorTree(e,t1,t2):n=e+1# Store adjacency lists of both trees.g1=[[]for_inrange(n+1)]g2=[[]for_inrange(n+1)]# Store edges of the first tree.foriinrange(0,2*e,2):g1[t1[i]].append(t1[i+1])# Store edges of the second tree.foriinrange(0,2*e,2):g2[t2[i]].append(t2[i+1])st=[]q=deque()# Start traversal from the root.st.append(1)q.append(1)whilestandq:a=st.pop()b=q.popleft()# Corresponding nodes must be the same.ifa!=b:returnFalse# Push children of the first tree into the stack.forchilding1[a]:st.append(child)# Store the remaining queue elements temporarily.temp=[]whileq:temp.append(q.popleft())# Push children of the second tree into the queue.forchilding2[b]:q.append(child)# Restore the previous queue elements.fornodeintemp:q.append(node)# Both traversals must finish together.returnnotstandnotq# Driver Codeif__name__=="__main__":e=2t1=[1,2,1,3]t2=[1,3,1,2]print("true"ifcheckMirrorTree(e,t1,t2)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{staticboolcheckMirrorTree(inte,int[]t1,int[]t2){intn=e+1;// Store adjacency lists of both trees.List<int>[]g1=newList<int>[n+1];List<int>[]g2=newList<int>[n+1];for(inti=0;i<=n;i++){g1[i]=newList<int>();g2[i]=newList<int>();}// Store edges of the first tree.for(inti=0;i<2*e;i+=2){g1[t1[i]].Add(t1[i+1]);}// Store edges of the second tree.for(inti=0;i<2*e;i+=2){g2[t2[i]].Add(t2[i+1]);}Stack<int>st=newStack<int>();Queue<int>q=newQueue<int>();// Start traversal from the root.st.Push(1);q.Enqueue(1);while(st.Count>0&&q.Count>0){inta=st.Pop();intb=q.Dequeue();// Corresponding nodes must be the same.if(a!=b)returnfalse;// Push children of the first tree into the// stack.foreach(intchilding1[a])st.Push(child);// Store the remaining queue elements// temporarily.List<int>temp=newList<int>();while(q.Count>0)temp.Add(q.Dequeue());// Push children of the second tree into the// queue.foreach(intchilding2[b])q.Enqueue(child);// Restore the previous queue elements.foreach(intnodeintemp)q.Enqueue(node);}// Both traversals must finish together.returnst.Count==0&&q.Count==0;}staticvoidMain(){inte=2;int[]t1={1,2,1,3};int[]t2={1,3,1,2};Console.WriteLine(checkMirrorTree(e,t1,t2)?"true":"false");}}
JavaScript
functioncheckMirrorTree(e,t1,t2){constn=e+1;// Store adjacency lists of both trees.constg1=Array.from({length:n+1},()=>[]);constg2=Array.from({length:n+1},()=>[]);// Store edges of the first tree.for(leti=0;i<2*e;i+=2){g1[t1[i]].push(t1[i+1]);}// Store edges of the second tree.for(leti=0;i<2*e;i+=2){g2[t2[i]].push(t2[i+1]);}constst=[];constq=[];// Start traversal from the root.st.push(1);q.push(1);while(st.length>0&&q.length>0){consta=st.pop();constb=q.shift();// Corresponding nodes must be the same.if(a!==b)returnfalse;// Push children of the first tree into the stack.for(constchildofg1[a])st.push(child);// Store the remaining queue elements temporarily.consttemp=[];while(q.length>0)temp.push(q.shift());// Push children of the second tree into the queue.for(constchildofg2[b])q.push(child);// Restore the previous queue elements.for(constnodeoftemp)q.push(node);}// Both traversals must finish together.returnst.length===0&&q.length===0;}// Driver codeconste=2;constt1=[1,2,1,3];constt2=[1,3,1,2];console.log(checkMirrorTree(e,t1,t2)?"true":"false");
Output
true
[Expected Approach] Stack-Based Child Order Comparison - O(e) Time and O(e) Space
The key observation is that two trees are mirror images if the children of every node appear in reverse order in the other tree.
We store the children of each node in the first tree using a stack, so the last child is checked first.
While traversing the edges of the second tree, each child must match the top of its parent's stack. If every edge matches, the two trees are mirror images.
Create a stack for every node and store the children of the first tree in their given order.
Traverse the edges of the second tree in the given order.
For each edge (u, v), check whether v matches the top child stored for u.
If it matches, pop that child from the stack.
If any child does not match, return false.
If all edges match, return true.
C++
#include<bits/stdc++.h>usingnamespacestd;boolcheckMirrorTree(inte,vector<int>&t1,vector<int>&t2){// Store children of each node of the first tree in a stack.vector<stack<int>>st(e+2);// Store all children of the first tree.for(inti=0;i<2*e;i+=2){st[t1[i]].push(t1[i+1]);}// Check children of the second tree in reverse order.for(inti=0;i<2*e;i+=2){intparent=t2[i];intchild=t2[i+1];// Child must match the top of the parent's stack.if(st[parent].empty()||st[parent].top()!=child)returnfalse;st[parent].pop();}returntrue;}intmain(){inte=2;vector<int>t1={1,2,1,3};vector<int>t2={1,3,1,2};cout<<(checkMirrorTree(e,t1,t2)?"true":"false");return0;}
Java
importjava.util.*;classGFG{staticbooleancheckMirrorTree(inte,int[]t1,int[]t2){// Store children of each node of the first tree in// a stack.Stack<Integer>[]st=newStack[e+2];for(inti=0;i<=e+1;i++){st[i]=newStack<>();}// Store all children of the first tree.for(inti=0;i<2*e;i+=2){st[t1[i]].push(t1[i+1]);}// Check children of the second tree in reverse// order.for(inti=0;i<2*e;i+=2){intparent=t2[i];intchild=t2[i+1];// Child must match the top of the parent's// stack.if(st[parent].isEmpty()||st[parent].peek()!=child)returnfalse;st[parent].pop();}returntrue;}publicstaticvoidmain(String[]args){inte=2;int[]t1={1,2,1,3};int[]t2={1,3,1,2};System.out.println(checkMirrorTree(e,t1,t2)?"true":"false");}}
Python
defcheckMirrorTree(e,t1,t2):# Store children of each node of the first tree in a stack.st=[[]for_inrange(e+2)]# Store all children of the first tree.foriinrange(0,2*e,2):st[t1[i]].append(t1[i+1])# Check children of the second tree in reverse order.foriinrange(0,2*e,2):parent=t2[i]child=t2[i+1]# Child must match the top of the parent's stack.ifnotst[parent]orst[parent][-1]!=child:returnFalsest[parent].pop()returnTrue# Driver Codeif__name__=="__main__":e=2t1=[1,2,1,3]t2=[1,3,1,2]print("true"ifcheckMirrorTree(e,t1,t2)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGFG{staticboolcheckMirrorTree(inte,int[]t1,int[]t2){// Store children of each node of the first tree in// a stack.Stack<int>[]st=newStack<int>[e+2];for(inti=0;i<=e+1;i++)st[i]=newStack<int>();// Store all children of the first tree.for(inti=0;i<2*e;i+=2)st[t1[i]].Push(t1[i+1]);// Check children of the second tree in reverse// order.for(inti=0;i<2*e;i+=2){intparent=t2[i];intchild=t2[i+1];// Child must match the top of the parent's// stack.if(st[parent].Count==0||st[parent].Peek()!=child)returnfalse;st[parent].Pop();}returntrue;}staticvoidMain(){inte=2;int[]t1={1,2,1,3};int[]t2={1,3,1,2};Console.WriteLine(checkMirrorTree(e,t1,t2)?"true":"false");}}
JavaScript
functioncheckMirrorTree(e,t1,t2){// Store children of each node of the first tree in a// stack.constst=Array.from({length:e+2},()=>[]);// Store all children of the first tree.for(leti=0;i<2*e;i+=2){st[t1[i]].push(t1[i+1]);}// Check children of the second tree in reverse order.for(leti=0;i<2*e;i+=2){constparent=t2[i];constchild=t2[i+1];// Child must match the top of the parent's stack.if(st[parent].length===0||st[parent][st[parent].length-1]!==child){returnfalse;}st[parent].pop();}returntrue;}// Driver codeconste=2;constt1=[1,2,1,3];constt2=[1,3,1,2];console.log(checkMirrorTree(e,t1,t2)?"true":"false");