Problem
Given the root
of a binary tree, return all duplicate subtrees.
For each kind of duplicate subtrees, you only need to return the root node of any one of them.
Two trees are duplicate if they have the same structure with the same node values.
Examples
Example 1:
graph TD A(1) A(1) --- B(2):::duplicate A --- C(3) B --- D(4):::duplicate B ~~~ N1:::hidden C --- E(2):::duplicate C --- F(4) E --- G(4):::duplicate E ~~~ N2:::hidden classDef duplicate fill:#FFD700,stroke:#000,stroke-width:1px,color:#000; classDef hidden display:none
|
|
Example 2:
graph TD A(2) A(2) --- B(1):::duplicate A(2) --- C(1):::duplicate classDef duplicate fill:#FFD700,stroke:#000,stroke-width:1px,color:#000;
|
|
Example 3:
graph TD A(2) A --- B(2):::duplicate A --- C(2):::duplicate B --- D(3):::duplicate B ~~~ N1:::hidden C --- E(3):::duplicate C ~~~ N2:::hidden classDef duplicate fill:#FFD700,stroke:#000,stroke-width:1px,color:#000; classDef hidden display:none
|
|
Solution
Method 1 - Using Serialization and Postorder Traversal
To solve the problem, the key is to uniquely identify each subtree using a serialization (string representation). Once we can serialize a subtree, we can check for duplicates. If we encounter the same serialization more than once, it means the subtree is a duplicate.
The approach involves:
- Traversing the tree using post-order traversal (left, right, root), as this ensures that every subtree is serialized only after its children are serialized.
- Using a map/dictionary to record the frequency of each subtree’s serialization.
- Returning the root of the subtrees that appear more than once.
Approach
- Post-order Traversal:
- Serialise each subtree based on its structure and node values.
- Include information from both children and the current node.
- HashMap in Java / Dictionary in Python:
- Store the frequency of each resulting serialization.
- Only save the root node of duplicate subtrees if the frequency is exactly 2.
- Result List:
- Maintain a list to store the nodes that represent duplicate subtrees.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
. Each node is visited once during traversal, and the serialization operation is constant for each node. - 🧺 Space complexity:
O(n)
. The space used is mainly due to the HashMap/Dictionary to store the serialization of subtrees and recursion stack during traversal.