Check mirror in n-ary tree

Last Updated : 27 Apr, 2025

Given two n-ary trees, determine whether they are mirror images of each other. Each tree is described by e edges, where e denotes the number of edges in both trees. Two arrays A[]and B[] are provided, where each array contains 2*e space-separated values representing the edges of both trees. Each edge is represented by two integers u and v, indicating an edge between node u and node v in the respective tree.

The task is to check whether the two trees are mirror images of each other.

Examples: 

Input: n = 3, e = 2, A[] = [1, 2, 1, 3], B[] = [1, 3, 1, 2]
Output: True
Explanation: As we can clearly see, the second tree is the mirror image of the first.

Input: n = 3, e = 2, A[] = [1, 2, 1, 3], B[] = [1, 2, 1, 3]
Output: False
Explanation: As we can clearly see, the second tree isn't mirror image of the first.
1 1
/ \ / \
2 3 2 3

Try It Yourself
redirect icon

Using Hash Map - O(e) time and O(n + e) space

The main idea is to use a Hash Map or Dictionary to store the relationships between nodes in the first tree. They key in the map is node number and values is a stack of nodes connected with it (or children of it) from left to right.
We then traverse the second tree and check if the children of the nodes are in reverse order compared to the first tree. This is how we check if the two trees are mirrors.

Below are detailed steps:

  • For each edge in the first tree, push the connected nodes into the stack of the parent node in the map.
  • For each node X in the second tree, compare the connected node a (top of the stack for node X in the map) with the connected node b (the current child of node X in the second tree).
  • If the values a and b don't match, return false, indicating the trees are not mirror images of each other.
  • If the values match, pop node X from the stack (as it has been correctly matched in the second tree).
C++
#include <iostream>
#include <unordered_map>
#include <stack>
using namespace std;

int checkMirror(int n, int e, int A[], int B[]) {
    unordered_map<int, stack<int>> mp;

    for (int i = 0; i < e; i++) {
        mp[A[2*i]].push(A[2*i+1]);
    }

    for (int i = 0; i < e; i++) {
        if (mp[B[2*i]].top() != B[2*i+1]) {
            return 0;
        }
        mp[B[2*i]].pop();
    }

    return 1;
}

int main() {
    int n = 3, e = 2;
    int A[] = {1, 2, 1, 3};
    int B[] = {1, 3, 1, 2};

    if (checkMirror(n, e, A, B))
        cout << "1";
    else
        cout << "0";

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

public class GfG {
    public static int checkMirror(int n, int e, int[] A, int[] B) {
        HashMap<Integer, Stack<Integer>> mp = new HashMap<>();

        for (int i = 0; i < e; i++) {
            mp.putIfAbsent(A[2 * i], new Stack<>());
            mp.get(A[2 * i]).push(A[2 * i + 1]);
        }

        for (int i = 0; i < e; i++) {
            if (mp.get(B[2 * i]).peek() != B[2 * i + 1]) {
                return 0;
            }
            mp.get(B[2 * i]).pop();
        }

        return 1;
    }

    public static void main(String[] args) {
        int n = 3, e = 2;
        int[] A = {1, 2, 1, 3};
        int[] B = {1, 3, 1, 2};

        if (checkMirror(n, e, A, B) == 1)
            System.out.println("1");
        else
            System.out.println("0");
    }
}
Python
def checkMirror(n, e, A, B):
    mp = {}

    for i in range(e):
        if A[2 * i] not in mp:
            mp[A[2 * i]] = []
        mp[A[2 * i]].append(A[2 * i + 1])

    for i in range(e):
        if mp[B[2 * i]][-1] != B[2 * i + 1]:
            return 0
        mp[B[2 * i]].pop()

    return 1

if __name__ == '__main__':
    n = 3
    e = 2
    A = [1, 2, 1, 3]
    B = [1, 3, 1, 2]

    if checkMirror(n, e, A, B):
        print("1")
    else:
        print("0")
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GfG {
    public static int CheckMirror(int n, int e, int[] A, int[] B) {
        Dictionary<int, Stack<int>> mp = new Dictionary<int, Stack<int>>();

        for (int i = 0; i < e; i++) {
            if (!mp.ContainsKey(A[2 * i])) {
                mp[A[2 * i]] = new Stack<int>();
            }
            mp[A[2 * i]].Push(A[2 * i + 1]);
        }

        for (int i = 0; i < e; i++) {
            if (mp[B[2 * i]].Peek() != B[2 * i + 1]) {
                return 0;
            }
            mp[B[2 * i]].Pop();
        }

        return 1;
    }

    static void Main() {
        int n = 3, e = 2;
        int[] A = {1, 2, 1, 3};
        int[] B = {1, 3, 1, 2};

        Console.WriteLine(CheckMirror(n, e, A, B) == 1 ? "1" : "0");
    }
}
JavaScript
function checkMirror(n, e, A, B) {
    const mp = {};

    for (let i = 0; i < e; i++) {
        if (!mp[A[2 * i]]) {
            mp[A[2 * i]] = [];
        }
        mp[A[2 * i]].push(A[2 * i + 1]);
    }

    for (let i = 0; i < e; i++) {
        if (mp[B[2 * i]][mp[B[2 * i]].length - 1] !== B[2 * i + 1]) {
            return 0;
        }
        mp[B[2 * i]].pop();
    }

    return 1;
}

const n = 3, e = 2;
const A = [1, 2, 1, 3];
const B = [1, 3, 1, 2];

console.log(checkMirror(n, e, A, B) ? '1' : '0');

Output
1

Time Complexity: O(e) for both building the map and checking the second tree.
Auxiliary Space: O(n + e), where n is the number of nodes (which may be proportional to e in typical tree structures) and e is the number of edges.

Stack-Queue Mirror Tree Comparison Method - O(e) time and O(e) space

The approach uses stacks and queues to check if two n-ary trees are mirror images.

For tree 1, child nodes are stored in stacks, and for tree 2, child nodes are stored in queues. The trees are compared by popping nodes from the stack for tree 1 and dequeuing nodes from the queue for tree 2. If the nodes at each position match in reverse order, the trees are mirrors; otherwise, they are not. If all comparisons succeed, the function returns true; if any mismatch occurs, it returns false.

C++
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;

int checkMirror(int n, int e, int A[], int B[]) {
    
    // Create vectors to store stacks and queues for each node
    vector<stack<int>> s;
    vector<queue<int>> q;

    // Initialize each vector element with an empty stack and queue
    for (int i = 0; i <= n; i++) {
        s.push_back(stack<int>());
        queue<int> queue;
        q.push_back(queue);
    }

    // Fill the stacks for tree 1 and queues for tree 2 based on given edges
    for (int i = 0; i < 2 * e; i += 2) {
        s[A[i]].push(A[i + 1]);  
        q[B[i]].push(B[i + 1]);  
    }

    // Now, compare nodes of both trees by taking out elements from stack and queue
    for (int i = 1; i <= n; i++) {
        
        // Ensure both the stack and queue are not empty before comparing
        while (!s[i].empty() && !q[i].empty()) {
            int a = s[i].top();  
            s[i].pop();  

            int b = q[i].front();  
            q[i].pop(); 
            
            // If the nodes don't match, the trees are not mirrors
            if (a != b) {
                return 0;
            }
        }
    }

    // If all comparisons are successful, return 1 (trees are mirror images)
    return 1;
}

int main() {
    int n = 3, e = 2;
    int A[] = {1, 2, 1, 3};  
    int B[] = {1, 3, 1, 2};  

    // Check if the trees are mirror images and print the result
    if (checkMirror(n, e, A, B) == 1) {
        cout << "1";  
    } else {
        cout << "0";  
    }

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

public class GfG {
    public static int checkMirror(int n, int e, int[] A, int[] B) {
        
        // Create lists to store stacks and queues for each node
        List<Stack<Integer>> s = new ArrayList<>();
        List<Queue<Integer>> q = new ArrayList<>();

        // Initialize each list element with an empty stack and queue
        for (int i = 0; i <= n; i++) {
            s.add(new Stack<>());
            q.add(new LinkedList<>());
        }

        // Fill the stacks for tree 1 and queues for tree 2 based on given edges
        for (int i = 0; i < 2 * e; i += 2) {
            s.get(A[i]).push(A[i + 1]);
            q.get(B[i]).offer(B[i + 1]);
        }

        // Now, compare nodes of both trees by taking out elements from stack and queue
        for (int i = 1; i <= n; i++) {
            
            // Ensure both the stack and queue are not empty before comparing
            while (!s.get(i).isEmpty() && !q.get(i).isEmpty()) {
                int a = s.get(i).pop();
                int b = q.get(i).poll();
                
                // If the nodes don't match, the trees are not mirrors
                if (a != b) {
                    return 0;
                }
            }
        }

        // If all comparisons are successful, return 1 (trees are mirror images)
        return 1;
    }

    public static void main(String[] args) {
        int n = 3, e = 2;
        int[] A = {1, 2, 1, 3};
        int[] B = {1, 3, 1, 2};

        // Check if the trees are mirror images and print the result
        if (checkMirror(n, e, A, B) == 1) {
            System.out.println("1");
        } else {
            System.out.println("0");
        }
    }
}
Python
# Define the function to check mirror

def checkMirror(n, e, A, B):
    
    # Create lists to store stacks and queues for each node
    s = [[] for _ in range(n + 1)]
    q = [[] for _ in range(n + 1)]

    # Fill the stacks for tree 1 and queues for tree 2 based on given edges
    for i in range(0, 2 * e, 2):
        s[A[i]].append(A[i + 1])
        q[B[i]].append(B[i + 1])

    # Now, compare nodes of both trees by taking out elements from stack and queue
    for i in range(1, n + 1):
        
        # Ensure both the stack and queue are not empty before comparing
        while s[i] and q[i]:
            a = s[i].pop()  # Pop from stack
            b = q[i].pop(0)  # Dequeue from queue
            # If the nodes don't match, the trees are not mirrors
            if a != b:
                return 0

    # If all comparisons are successful, return 1 (trees are mirror images)
    return 1

if __name__ == '__main__':
    n = 3
    e = 2
    A = [1, 2, 1, 3]
    B = [1, 3, 1, 2]

    # Check if the trees are mirror images and print the result
    if checkMirror(n, e, A, B) == 1:
        print("1")
    else:
        print("0")
C#
using System;
using System.Collections.Generic;

class GfG {
    public static int CheckMirror(int n, int e, int[] A, int[] B) {
        
        // Create lists to store stacks and queues for each node
        List<Stack<int>> s = new List<Stack<int>>();
        List<Queue<int>> q = new List<Queue<int>>();

        // Initialize each list element with an empty stack and queue
        for (int i = 0; i <= n; i++) {
            s.Add(new Stack<int>());
            q.Add(new Queue<int>());
        }

        // Fill the stacks for tree 1 and queues for tree 2 based on given edges
        for (int i = 0; i < 2 * e; i += 2) {
            s[A[i]].Push(A[i + 1]);
            q[B[i]].Enqueue(B[i + 1]);
        }

        // Now, compare nodes of both trees by taking out elements from stack and queue
        for (int i = 1; i <= n; i++) {
            // Ensure both the stack and queue are not empty before comparing
            while (s[i].Count > 0 && q[i].Count > 0) {
                int a = s[i].Pop();
                int b = q[i].Dequeue();
                
                // If the nodes don't match, the trees are not mirrors
                if (a != b) {
                    return 0;
                }
            }
        }

        // If all comparisons are successful, return 1 (trees are mirror images)
        return 1;
    }

    static void Main() {
        int n = 3, e = 2;
        int[] A = {1, 2, 1, 3};
        int[] B = {1, 3, 1, 2};

        // Check if the trees are mirror images and print the result
        if (CheckMirror(n, e, A, B) == 1) {
            Console.WriteLine("1");
        } else {
            Console.WriteLine("0");
        }
    }
}
JavaScript
function checkMirror(n, e, A, B) {
    
    // Create arrays to store stacks and queues for each node
    let s = Array.from({length: n + 1}, () => []);
    let q = Array.from({length: n + 1}, () => []);

    // Fill the stacks for tree 1 and queues for tree 2 based on given edges
    for (let i = 0; i < 2 * e; i += 2) {
        s[A[i]].push(A[i + 1]);
        q[B[i]].push(B[i + 1]);
    }

    // Now, compare nodes of both trees by taking out elements from stack and queue
    for (let i = 1; i <= n; i++) {
        
        // Ensure both the stack and queue are not empty before comparing
        while (s[i].length > 0 && q[i].length > 0) {
            let a = s[i].pop();  
            let b = q[i].shift();
            
            // If the nodes don't match, the trees are not mirrors
            if (a !== b) {
                return 0;
            }
        }
    }

    // If all comparisons are successful, return 1 (trees are mirror images)
    return 1;
}

const n = 3, e = 2;
const A = [1, 2, 1, 3];
const B = [1, 3, 1, 2];

// Check if the trees are mirror images and print the result
console.log(checkMirror(n, e, A, B) === 1 ? "1" : "0");

Output
1

Time complexity: O(e), where e is the number of edges
Auxiliary space: O(e)

Comment