Check Mirror in N-ary tree

Last Updated : 28 Aug, 2026

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:

frame_3286

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:

frame_3219

As we can clearly see, the second tree isn't mirror image of the first.

Try It Yourself
redirect icon

[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>
using namespace std;

bool checkMirrorTree(int e, vector<int> &t1, vector<int> &t2)
{
    int n = e + 1;

    // Store adjacency lists of both trees.
    vector<vector<int>> g1(n + 1), g2(n + 1);

    // Store edges of the first tree.
    for (int i = 0; i < 2 * e; i += 2)
    {
        g1[t1[i]].push_back(t1[i + 1]);
    }

    // Store edges of the second tree.
    for (int i = 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())
    {
        int a = st.top();
        st.pop();

        int b = q.front();
        q.pop();

        // Corresponding nodes must be the same.
        if (a != b)
            return false;

        // Push children of the first tree into the stack.
        for (int child : 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 (int child : g2[b])
            q.push(child);

        // Restore the previous queue elements.
        for (int node : temp)
            q.push(node);
    }

    // Both traversals must finish together.
    return st.empty() && q.empty();
}

int main()
{
    int e = 2;

    vector<int> t1 = {1, 2, 1, 3};
    vector<int> t2 = {1, 3, 1, 2};

    cout << (checkMirrorTree(e, t1, t2) ? "true" : "false") << endl;

    return 0;
}
Java
import java.util.*;

class GFG {
    static boolean checkMirrorTree(int e, int[] t1, int[] t2)
    {
        int n = e + 1;

        // Store adjacency lists of both trees.
        ArrayList<Integer>[] g1 = new ArrayList[n + 1];
        ArrayList<Integer>[] g2 = new ArrayList[n + 1];

        for (int i = 0; i <= n; i++) {
            g1[i] = new ArrayList<>();
            g2[i] = new ArrayList<>();
        }

        // Store edges of the first tree.
        for (int i = 0; i < 2 * e; i += 2) {
            g1[t1[i]].add(t1[i + 1]);
        }

        // Store edges of the second tree.
        for (int i = 0; i < 2 * e; i += 2) {
            g2[t2[i]].add(t2[i + 1]);
        }

        Stack<Integer> st = new Stack<>();
        Queue<Integer> q = new LinkedList<>();

        // Start traversal from the root.
        st.push(1);
        q.add(1);

        while (!st.empty() && !q.isEmpty()) {
            int a = st.pop();
            int b = q.poll();

            // Corresponding nodes must be the same.
            if (a != b)
                return false;

            // Push children of the first tree into the
            // stack.
            for (int child : g1[a])
                st.push(child);

            // Store the remaining queue elements
            // temporarily.
            ArrayList<Integer> temp = new ArrayList<>();

            while (!q.isEmpty())
                temp.add(q.poll());

            // Push children of the second tree into the
            // queue.
            for (int child : g2[b])
                q.add(child);

            // Restore the previous queue elements.
            for (int node : temp)
                q.add(node);
        }

        // Both traversals must finish together.
        return st.isEmpty() && q.isEmpty();
    }

    public static void main(String[] args)
    {
        int e = 2;

        int[] t1 = { 1, 2, 1, 3 };
        int[] t2 = { 1, 3, 1, 2 };

        System.out.println(checkMirrorTree(e, t1, t2) ? "true"
                                                      : "false");
    }
}
Python
from collections import deque


def checkMirrorTree(e, t1, t2):
    n = e + 1

    # Store adjacency lists of both trees.
    g1 = [[] for _ in range(n + 1)]
    g2 = [[] for _ in range(n + 1)]

    # Store edges of the first tree.
    for i in range(0, 2 * e, 2):
        g1[t1[i]].append(t1[i + 1])

    # Store edges of the second tree.
    for i in range(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)

    while st and q:
        a = st.pop()
        b = q.popleft()

        # Corresponding nodes must be the same.
        if a != b:
            return False

        # Push children of the first tree into the stack.
        for child in g1[a]:
            st.append(child)

        # Store the remaining queue elements temporarily.
        temp = []

        while q:
            temp.append(q.popleft())

        # Push children of the second tree into the queue.
        for child in g2[b]:
            q.append(child)

        # Restore the previous queue elements.
        for node in temp:
            q.append(node)

    # Both traversals must finish together.
    return not st and not q


# Driver Code
if __name__ == "__main__":
    e = 2

    t1 = [1, 2, 1, 3]
    t2 = [1, 3, 1, 2]

    print("true" if checkMirrorTree(e, t1, t2) else "false")
C#
using System;
using System.Collections.Generic;

class GFG {
    static bool checkMirrorTree(int e, int[] t1, int[] t2)
    {
        int n = e + 1;

        // Store adjacency lists of both trees.
        List<int>[] g1 = new List<int>[ n + 1 ];
        List<int>[] g2 = new List<int>[ n + 1 ];

        for (int i = 0; i <= n; i++) {
            g1[i] = new List<int>();
            g2[i] = new List<int>();
        }

        // Store edges of the first tree.
        for (int i = 0; i < 2 * e; i += 2) {
            g1[t1[i]].Add(t1[i + 1]);
        }

        // Store edges of the second tree.
        for (int i = 0; i < 2 * e; i += 2) {
            g2[t2[i]].Add(t2[i + 1]);
        }

        Stack<int> st = new Stack<int>();
        Queue<int> q = new Queue<int>();

        // Start traversal from the root.
        st.Push(1);
        q.Enqueue(1);

        while (st.Count > 0 && q.Count > 0) {
            int a = st.Pop();
            int b = q.Dequeue();

            // Corresponding nodes must be the same.
            if (a != b)
                return false;

            // Push children of the first tree into the
            // stack.
            foreach(int child in g1[a]) st.Push(child);

            // Store the remaining queue elements
            // temporarily.
            List<int> temp = new List<int>();

            while (q.Count > 0)
                temp.Add(q.Dequeue());

            // Push children of the second tree into the
            // queue.
            foreach(int child in g2[b]) q.Enqueue(child);

            // Restore the previous queue elements.
            foreach(int node in temp) q.Enqueue(node);
        }

        // Both traversals must finish together.
        return st.Count == 0 && q.Count == 0;
    }

    static void Main()
    {
        int e = 2;

        int[] t1 = { 1, 2, 1, 3 };
        int[] t2 = { 1, 3, 1, 2 };

        Console.WriteLine(checkMirrorTree(e, t1, t2) ? "true"
                                                     : "false");
    }
}
JavaScript
function checkMirrorTree(e, t1, t2)
{
    const n = e + 1;

    // Store adjacency lists of both trees.
    const g1 = Array.from({length : n + 1}, () => []);
    const g2 = Array.from({length : n + 1}, () => []);

    // Store edges of the first tree.
    for (let i = 0; i < 2 * e; i += 2) {
        g1[t1[i]].push(t1[i + 1]);
    }

    // Store edges of the second tree.
    for (let i = 0; i < 2 * e; i += 2) {
        g2[t2[i]].push(t2[i + 1]);
    }

    const st = [];
    const q = [];

    // Start traversal from the root.
    st.push(1);
    q.push(1);

    while (st.length > 0 && q.length > 0) {
        const a = st.pop();
        const b = q.shift();

        // Corresponding nodes must be the same.
        if (a !== b)
            return false;

        // Push children of the first tree into the stack.
        for (const child of g1[a])
            st.push(child);

        // Store the remaining queue elements temporarily.
        const temp = [];

        while (q.length > 0)
            temp.push(q.shift());

        // Push children of the second tree into the queue.
        for (const child of g2[b])
            q.push(child);

        // Restore the previous queue elements.
        for (const node of temp)
            q.push(node);
    }

    // Both traversals must finish together.
    return st.length === 0 && q.length === 0;
}

// Driver code
const e = 2;

const t1 = [ 1, 2, 1, 3 ];
const t2 = [ 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>
using namespace std;

bool checkMirrorTree(int e, 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 (int i = 0; i < 2 * e; i += 2)
    {
        st[t1[i]].push(t1[i + 1]);
    }

    // Check children of the second tree in reverse order.
    for (int i = 0; i < 2 * e; i += 2)
    {
        int parent = t2[i];
        int child = t2[i + 1];

        // Child must match the top of the parent's stack.
        if (st[parent].empty() || st[parent].top() != child)
            return false;

        st[parent].pop();
    }

    return true;
}

int main()
{
    int e = 2;

    vector<int> t1 = {1, 2, 1, 3};
    vector<int> t2 = {1, 3, 1, 2};

    cout << (checkMirrorTree(e, t1, t2) ? "true" : "false");

    return 0;
}
Java
import java.util.*;

class GFG {
    static boolean checkMirrorTree(int e, int[] t1, int[] t2)
    {
        // Store children of each node of the first tree in
        // a stack.
        Stack<Integer>[] st = new Stack[e + 2];

        for (int i = 0; i <= e + 1; i++) {
            st[i] = new Stack<>();
        }

        // Store all children of the first tree.
        for (int i = 0; i < 2 * e; i += 2) {
            st[t1[i]].push(t1[i + 1]);
        }

        // Check children of the second tree in reverse
        // order.
        for (int i = 0; i < 2 * e; i += 2) {
            int parent = t2[i];
            int child = t2[i + 1];

            // Child must match the top of the parent's
            // stack.
            if (st[parent].isEmpty()
                || st[parent].peek() != child)
                return false;

            st[parent].pop();
        }

        return true;
    }

    public static void main(String[] args)
    {
        int e = 2;

        int[] t1 = { 1, 2, 1, 3 };
        int[] t2 = { 1, 3, 1, 2 };

        System.out.println(checkMirrorTree(e, t1, t2) ? "true"
                                                      : "false");
    }
}
Python
def checkMirrorTree(e, t1, t2):
    
    # Store children of each node of the first tree in a stack.
    st = [[] for _ in range(e + 2)]

    # Store all children of the first tree.
    for i in range(0, 2 * e, 2):
        st[t1[i]].append(t1[i + 1])

    # Check children of the second tree in reverse order.
    for i in range(0, 2 * e, 2):
        parent = t2[i]
        child = t2[i + 1]

        # Child must match the top of the parent's stack.
        if not st[parent] or st[parent][-1] != child:
            return False

        st[parent].pop()

    return True


# Driver Code
if __name__ == "__main__":
    e = 2

    t1 = [1, 2, 1, 3]
    t2 = [1, 3, 1, 2]

    print("true" if checkMirrorTree(e, t1, t2) else "false")
C#
using System;
using System.Collections.Generic;

class GFG {
    static bool checkMirrorTree(int e, int[] t1, int[] t2)
    {
        // Store children of each node of the first tree in
        // a stack.
        Stack<int>[] st = new Stack<int>[ e + 2 ];

        for (int i = 0; i <= e + 1; i++)
            st[i] = new Stack<int>();

        // Store all children of the first tree.
        for (int i = 0; i < 2 * e; i += 2)
            st[t1[i]].Push(t1[i + 1]);

        // Check children of the second tree in reverse
        // order.
        for (int i = 0; i < 2 * e; i += 2) {
            int parent = t2[i];
            int child = t2[i + 1];

            // Child must match the top of the parent's
            // stack.
            if (st[parent].Count == 0
                || st[parent].Peek() != child)
                return false;

            st[parent].Pop();
        }

        return true;
    }

    static void Main()
    {
        int e = 2;

        int[] t1 = { 1, 2, 1, 3 };
        int[] t2 = { 1, 3, 1, 2 };

        Console.WriteLine(checkMirrorTree(e, t1, t2) ? "true"
                                                     : "false");
    }
}
JavaScript
function checkMirrorTree(e, t1, t2)
{
    // Store children of each node of the first tree in a
    // stack.
    const st = Array.from({length : e + 2}, () => []);

    // Store all children of the first tree.
    for (let i = 0; i < 2 * e; i += 2) {
        st[t1[i]].push(t1[i + 1]);
    }

    // Check children of the second tree in reverse order.
    for (let i = 0; i < 2 * e; i += 2) {
        const parent = t2[i];
        const child = 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) {
            return false;
        }

        st[parent].pop();
    }

    return true;
}

// Driver code
const e = 2;

const t1 = [ 1, 2, 1, 3 ];
const t2 = [ 1, 3, 1, 2 ];

console.log(checkMirrorTree(e, t1, t2) ? "true" : "false");

Output
true
Comment