Introduction
Given two binary trees, we need to check whether the nodes at every corresponding level are anagrams of each other.
Two levels are considered anagrams when they contain the same values with the same frequencies, but the order of the values does not matter.
For example:
Tree 1 Level: [3, 2]
Tree 2 Level: [2, 3]
These two levels are anagrams because both contain:
2 → 1 time
3 → 1 time
Therefore, the levels are considered equal.
Example
Consider the following two trees:
Tree 1:
1
/ \
3 2
/ \
5 4
Tree 2:
1
/ \
2 3
/ \
4 5
Now compare the levels.
Level 0
Tree 1 → [1]
Tree 2 → [1]
Both contain 1.
So:
Level 0 → Anagram
Level 1
Tree 1 → [3, 2]
Tree 2 → [2, 3]
The order is different, but the values and frequencies are the same.
Level 1 → Anagram
Level 2
Tree 1 → [5, 4]
Tree 2 → [4, 5]
Again, both contain the same values.
Level 2 → Anagram
Therefore, the result is:
true
Main Concept
The important concept used in this problem is Level Order Traversal, also called Breadth-First Search (BFS).
A queue is used to process the tree level by level.
For each level:
Find the number of nodes in that level.
Remove those nodes from the queue.
Store their values and frequencies in a
HashMap.Add their children to the queue.
Do the same for the second tree.
Compare the two frequency maps.
If any level has different values or frequencies, the answer is immediately false.
Why HashMap?
We cannot simply compare the values in the order they appear.
For example:
[3, 2]
[2, 3]
The arrays are different if compared directly:
3 != 2
But they are anagrams.
So we need to compare frequencies instead.
We can store:
Tree 1:
3 → 1
2 → 1
and:
Tree 2:
2 → 1
3 → 1
The two maps are equal.
This also handles duplicate values.
For example:
Tree 1 → [2, 3, 2]
Tree 2 → [3, 2, 2]
Frequency map:
2 → 2
3 → 1
for both trees.
Therefore, they are anagrams.
Java Code
import java.util.*;
class Solution {
public boolean areAnagrams(Node root1, Node root2) {
if (root1 == null && root2 == null)
return true;
if (root1 == null || root2 == null)
return false;
Queue<Node> q1 = new LinkedList<>();
Queue<Node> q2 = new LinkedList<>();
q1.add(root1);
q2.add(root2);
while (!q1.isEmpty() && !q2.isEmpty()) {
int size1 = q1.size();
int size2 = q2.size();
// Both levels must contain the same number of nodes
if (size1 != size2)
return false;
HashMap<Integer, Integer> map1 = new HashMap<>();
HashMap<Integer, Integer> map2 = new HashMap<>();
for (int i = 0; i < size1; i++) {
Node node1 = q1.poll();
Node node2 = q2.poll();
// Store frequency of values in Tree 1
map1.put(
node1.data,
map1.getOrDefault(node1.data, 0) + 1
);
// Store frequency of values in Tree 2
map2.put(
node2.data,
map2.getOrDefault(node2.data, 0) + 1
);
// Add children of Tree 1
if (node1.left != null)
q1.add(node1.left);
if (node1.right != null)
q1.add(node1.right);
// Add children of Tree 2
if (node2.left != null)
q2.add(node2.left);
if (node2.right != null)
q2.add(node2.right);
}
// Compare current level
if (!map1.equals(map2))
return false;
}
// Both trees must have the same number of levels
return q1.isEmpty() && q2.isEmpty();
}
}
Code Explanation
1. Check for null roots
if (root1 == null && root2 == null)
return true;
if (root1 == null || root2 == null)
return false;
If both trees are empty, they are considered equal.
If only one tree is empty, they cannot have matching levels.
2. Create two queues
Queue<Node> q1 = new LinkedList<>();
Queue<Node> q2 = new LinkedList<>();
We use one queue for each tree.
Initially, add the root nodes:
q1.add(root1);
q2.add(root2);
The queues allow us to process the trees level by level.

Join the conversation! Your thoughts help the community grow.