medium Clone Binary Tree With Random Pointer
Problem Statement
You are given a binary tree where each node has an additional pointer called the random pointer. This random pointer may point to any other node in the tree or could be set to null.
Create and return a deep copy of this binary tree.
In the input, each node is represented by a pair [val, random_index]:
- val is an integer that represents the value of the node.
- random_index is the index of the node (in the input list) to which the random pointer is pointing, or
nullif it does not point to any node.
The deep copy must replicate both the structure of the tree and the configuration of the random pointers.
Examples
Example 1:
- Input: root = [[3, 1], [9, null], [20, 0], [15, 2], [7, null]]
- Expected Output: [[3, 1], [9, null], [20, 0], [15, 2], [7, null]]
- Justification: The output is a deep copy of the original tree.
Example 2:
- Input: [[5, 4], [12, 0], [7, null], [2, 1], [9, 3]]
- Expected Output: [[5, 4], [12, 0], [7, null], [2, 1], [9, 3]]
- Justification: The output is a deep copy of the original tree.
Example 3:
- Input: root = [[1, 2], [4, null], [3, 0], [2, 1], [6, null]]
- Expected Output: [[1, 2], [4, null], [3, 0], [2, 1], [6, null]]
- Justification: The output is a deep copy of the original tree.
Constraints:
- The number of nodes in the tree is in the range [0, 1000].
- 1 <= Node.val <= 106
Try it yourself
Try solving this question here:
✅ Solution Clone Binary Tree With Random Pointer
Problem Statement
You are given a binary tree where each node has an additional pointer called the random pointer. This random pointer may point to any other node in the tree or could be set to null.
Create and return a deep copy of this binary tree.
In the input, each node is represented by a pair [val, random_index]:
- val is an integer that represents the value of the node.
- random_index is the index of the node (in the input list) to which the random pointer is pointing, or
nullif it does not point to any node.
The deep copy must replicate both the structure of the tree and the configuration of the random pointers.
Examples
Example 1:
- Input: root = [[3, 1], [9, null], [20, 0], [15, 2], [7, null]]
- Expected Output: [[3, 1], [9, null], [20, 0], [15, 2], [7, null]]
- Justification: The output is a deep copy of the original tree.
Example 2:
- Input: [[5, 4], [12, 0], [7, null], [2, 1], [9, 3]]
- Expected Output: [[5, 4], [12, 0], [7, null], [2, 1], [9, 3]]
- Justification: The output is a deep copy of the original tree.
Example 3:
- Input: root = [[1, 2], [4, null], [3, 0], [2, 1], [6, null]]
- Expected Output: [[1, 2], [4, null], [3, 0], [2, 1], [6, null]]
- Justification: The output is a deep copy of the original tree.
Constraints:
- The number of nodes in the tree is in the range [0, 1000].
- 1 <= Node.val <= 106
Solution
To solve the problem of cloning a binary tree where each node has an additional random pointer, we use a combination of recursion and a hash map to efficiently create a deep copy. The hash map keeps track of each original node and its corresponding cloned node, which helps us manage the random pointers. The recursive approach ensures that we visit each node exactly once, making a copy and assigning left, right, and random pointers correctly.
The solution begins by checking if the input tree is empty. If so, it returns null since there is nothing to copy. For non-empty trees, the solution initiates the cloning process from the root. It recursively traverses the original tree, copying nodes while maintaining their connections. The hash map helps to quickly find cloned nodes whenever they are needed, especially for handling the random pointers.
Step-by-Step Algorithm
-
Check if the root is
null:- If the input tree is empty (
root == null), returnnullbecause there is no tree to clone.
- If the input tree is empty (
-
Initialize a HashMap:
- Create a
HashMap<Node, Node>calledclonedMapto store the mapping of each original node to its corresponding cloned node. - This map helps to quickly access the cloned version of a node when needed, especially for handling random pointers.
- Create a
-
Start cloning the tree from the root node:
- Call the recursive function
cloneNodewith the root node and theclonedMap. - The
cloneNodefunction will handle the cloning process for each node recursively.
- Call the recursive function
-
In the
cloneNodefunction:- Base Case: If the input node is
null, returnnullbecause there is nothing to clone. - Check for Existing Cloned Node: If the input node has already been cloned (i.e., it is present in
clonedMap), return the corresponding cloned node from the map. - Clone the Current Node:
- Create a new
Nodeinstance (newNode) as a copy of the original node (with the same value). - Store the mapping between the original node and the new cloned node in the
clonedMap.
- Create a new
- Recursively Clone the Children:
- Call
cloneNoderecursively for the left and right children of the original node. - Assign the returned cloned left and right children to the
leftandrightpointers ofnewNode.
- Call
- Recursively Clone the Random Pointer:
- Call
cloneNoderecursively for the random pointer of the original node. - Assign the returned cloned node to the
randompointer ofnewNode.
- Call
- Return the Cloned Node: Return the cloned node (
newNode) after its children and random pointers are set.
- Base Case: If the input node is
-
Return the Cloned Root Node:
- After completing the recursive cloning process, return the result of
cloneNode(root)as the cloned root of the entire tree.
- After completing the recursive cloning process, return the result of
Algorithm Walkthrough
Input: [[3, 1], [9, null], [20, 0], [15, 2], [7, null]]:
-
Initial Function Call:
- Call
copyRandomBinaryTree(root)withrootbeing the node with value3. - Initialize
clonedMapas an emptyHashMap<Node, Node>.
- Call
-
Start Cloning from Root (Node
3):- Call
cloneNode(3). - Since Node
3is notnulland not inclonedMap, create a new nodenewNodewith value3. - Add the mapping
3 -> newNodetoclonedMap.
- Call
-
Recursively Clone Left Child (Node
9):- Call
cloneNode(9). - Since Node
9is notnulland not inclonedMap, create a new nodenewNodewith value9. - Add the mapping
9 -> newNodetoclonedMap.
- Call
-
Recursively Clone Left Child of Node
9(Node15):- Call
cloneNode(15). - Since Node
15is notnulland not inclonedMap, create a new nodenewNodewith value15. - Add the mapping
15 -> newNodetoclonedMap. - Node
15has no children, so recursive callscloneNode(null)for both left and right children returnnull. - Assign
nulltonewNode.leftandnewNode.right. - Node
15's random pointer points to Node20. Since Node20is not yet cloned, recursively callcloneNode(20)to clone it.
- Call
-
Recursively Clone Node
20(from Node15's random pointer):- Call
cloneNode(20). - Since Node
20is notnulland not inclonedMap, create a new nodenewNodewith value20. - Add the mapping
20 -> newNodetoclonedMap. - Node
20has no children, so recursive callscloneNode(null)for both left and right children returnnull. - Assign
nulltonewNode.leftandnewNode.right. - Node
20's random pointer points to Node3. Since Node3is already cloned, useclonedMapto find its clone and set it asnewNode.random. - Return the cloned node
newNodefor Node20.
- Call
-
Finish Cloning Node
15:- Node
15's random pointer now correctly points to the cloned Node20. - Return the cloned node
newNodefor Node15.
- Node
-
Recursively Clone Right Child of Node
9(Node7):- Call
cloneNode(7). - Since Node
7is notnulland not inclonedMap, create a new nodenewNodewith value7. - Add the mapping
7 -> newNodetoclonedMap. - Node
7has no children, so recursive callscloneNode(null)for both left and right children returnnull. - Assign
nulltonewNode.leftandnewNode.right. - Node
7has no random pointer (random = null), so the recursive callcloneNode(null)for the random pointer returnsnull. - Assign
nulltonewNode.random. - Return the cloned node
newNodefor Node7.
- Call
-
Finish Cloning Node
9:- Assign the cloned nodes for
9's left and right children (15and7) tonewNode.leftandnewNode.right. - Node
9has no random pointer (random = null), sonewNode.randomremainsnull. - Return the cloned node
newNodefor Node9.
- Assign the cloned nodes for
-
Recursively Clone Right Child of Root Node
3(Node20):- Node
20has already been cloned when cloning Node15's random pointer. - Retrieve the cloned node for
20fromclonedMap.
- Node
-
Finish Cloning Root Node
3:- Assign the cloned nodes for
3's left and right children (9and20) tonewNode.leftandnewNode.right. - Node
3's random pointer points to Node9. Since Node9is already cloned, useclonedMapto find its clone and set it asnewNode.random. - Return the cloned root node
newNode.
- Assign the cloned nodes for
-
Final Output:
- The cloned tree is returned with the correct structure and all random pointers replicated exactly as in the original tree.
Code
import java.util.HashMap;
// TreeNode class definition with value, left, right, and random pointers
// class TreeNode {
// public int val;
// public TreeNode left;
// public TreeNode right;
// public TreeNode random;
// // Constructor to initialize a TreeNode with a given value
// public TreeNode(int val) {
// this.val = val;
// this.left = null;
// this.right = null;
// this.random = null;
// }
// }
class Solution {
// Method to deep copy the binary tree with random pointers
public TreeNode copyRandomBinaryTree(TreeNode root) {
// If the original tree is empty, return null
if (root == null) return null;
// HashMap to store the mapping of original nodes to their cloned counterparts
HashMap<TreeNode, TreeNode> clonedMap = new HashMap<>();
// Start the cloning process from the root
return cloneNode(root, clonedMap);
}
// Helper method to clone a given node
private TreeNode cloneNode(
TreeNode node,
HashMap<TreeNode, TreeNode> clonedMap
) {
// Base case: If the node is null, return null
if (node == null) return null;
// If the node has already been cloned, return the cloned node from the map
if (clonedMap.containsKey(node)) return clonedMap.get(node);
// Create a new node as a deep copy of the original node
TreeNode newNode = new TreeNode(node.val);
// Add the new cloned node to the map
clonedMap.put(node, newNode);
// Recursively clone the left and right children and assign them to the cloned node
newNode.left = cloneNode(node.left, clonedMap);
newNode.right = cloneNode(node.right, clonedMap);
// Recursively clone the random pointer and assign it to the cloned node
newNode.random = cloneNode(node.random, clonedMap);
// Return the cloned node
return newNode;
}
public static void main(String[] args) {
Solution solution = new Solution();
// Creating the original tree for Example 1
TreeNode root = new TreeNode(3);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
// Setting up random pointers
root.random = root.left;
root.left.random = null;
root.right.random = root;
root.right.left.random = root.right;
root.right.right.random = null;
// Cloning the binary tree
TreeNode clonedRoot = solution.copyRandomBinaryTree(root);
// Printing the original tree nodes
System.out.println("Original Tree:");
printNodeDetails(root, "root");
printNodeDetails(root.left, "root.left");
printNodeDetails(root.right, "root.right");
printNodeDetails(root.right.left, "root.right.left");
printNodeDetails(root.right.right, "root.right.right");
// Printing the cloned tree nodes
System.out.println("\nCloned Tree:");
printNodeDetails(clonedRoot, "clonedRoot");
printNodeDetails(clonedRoot.left, "clonedRoot.left");
printNodeDetails(clonedRoot.right, "clonedRoot.right");
printNodeDetails(clonedRoot.right.left, "clonedRoot.right.left");
printNodeDetails(clonedRoot.right.right, "clonedRoot.right.right");
}
// Helper method to print detailed node information
private static void printNodeDetails(TreeNode node, String nodeName) {
if (node == null) return;
System.out.println(
nodeName +
".val = " +
node.val +
", " +
nodeName +
".random = " +
(node.random != null ? node.random.val : "null")
);
}
}
Complexity Analysis
Time Complexity
The time complexity of the solution is N is the number of nodes in the binary tree. This is because we are visiting each node exactly once to create a copy of it, and then processing its left, right, and random pointers.
The hash map operations (inserting and looking up nodes) are on average
Space Complexity
The space complexity is
Additionally, the recursive stack can also go up to
🤖 Don't fully get this? Learn it with Claude
Stuck on Clone Binary Tree With Random Pointer? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Clone Binary Tree With Random Pointer** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Clone Binary Tree With Random Pointer** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Clone Binary Tree With Random Pointer**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Clone Binary Tree With Random Pointer**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.