0% completed
You are given a linked list where each node contains an additional random pointer. This pointer could point to any node in the list or be null
.
Create a deep copy of this linked list. The deep copy should have n
new nodes, where each new node's value matches the value of its corresponding node in the original list. Additionally, both the next
and random
pointers of the new nodes should point to the new nodes in the copied list.
The pointers in the copied list should maintain the same structure as the original list. None of the pointers in the new list should reference any node in the original list.
For instance, if in the original list, node X has a random pointer to node Y (X.random -> Y
), then in the copied list, the corresponding nodes x and y should have a random pointer such that x.random -> y
.
The linked list is represented in the input/output as a list of n
nodes. Each node is represented as a pair of [val, randomIndex]
where:
val
: It is an integer representing Node.valrandomIndex:
The index of the node (range from 0
to n-1
) that the random pointer points to, or null if it does not point to any node.Given a head
of the linked list, return the head of the newly copied linked list.
[[3, 1], [4, null], [5, 0], [7, 2]]
[[3, 1], [4, null], [5, 0], [7, 2]]
[[1, 2], [2, 0], [3, 1]]
[[1, 2], [2, 0], [3, 1]]
[[8, 2], [9, null], [7, 1]]
[[8, 2], [9, null], [7, 1]]
Constraints:
Node.random
is null or is pointing to some node in the linked list.To solve this problem, we make three passes over the original linked list to create a deep copy that maintains the same next
and random
pointer structure as the original list. In the first pass, we insert a copy of each node right next to the original node. This helps us easily link the next
pointers of the copied nodes. During the second pass, we set up the random
pointers for the copied nodes using the established relationship between the original nodes and their copies. Finally, in the third pass, we separate the original and copied nodes, restoring the original list and forming the deep-copied list.
This approach is efficient because it only traverses the list three times, maintaining a linear time complexity of O(n). The algorithm avoids using extra space by cleverly utilizing the linked list structure to temporarily store the copied nodes next to their originals. This enables us to keep track of the next
and random
pointers without additional data structures, making the solution space-efficient with O(1) extra space.
Check for Empty List:
head
is null
, return null
. This handles the edge case where the input list is empty.First Pass: Create and Insert Copied Nodes:
current
to the head
of the original list.current
is not null
:
current
), create a new node copy
with the same value (current.val
).next
pointer of copy
to current.next
.copy
right after current
by setting current.next
to copy
.current
to copy.next
(i.e., the next original node).Second Pass: Set Random Pointers for Copied Nodes:
current
to the head
of the original list.current
is not null
:
current.random
is not null
, set the random
pointer of current.next
(the copied node) to current.random.next
(the copy of the node current.random
points to).current
to current.next.next
(i.e., the next original node).Third Pass: Separate the Original and Copied Lists:
current
to the head
of the original list.copiedHead
to head.next
(the head of the copied list).copy
to iterate over the copied list, initially set to copiedHead
.current
is not null
:
current.next
to current.next.next
to restore the original list.copy.next
is not null
, set copy.next
to copy.next.next
to form the copied list. This steps removes the node of the original list.current
and copy
to their respective next
nodes.Return the Head of the Copied List:
copiedHead
, which points to the head of the deep-copied linked list.Let's walk through the algorithm using the input head = [[3, 1], [4, null], [5, 0], [7, 2]]
.
3
, Random Pointer -> Node at index 1
(Node with value 4
)4
, Random Pointer -> null
5
, Random Pointer -> Node at index 0
(Node with value 3
)7
, Random Pointer -> Node at index 2
(Node with value 5
)Start with current
at Node 1 (Value 3
):
Node 1'
(Value 3
).Node 1'
after Node 1:
3 -> 3' -> 4 -> 5 -> 7
.current
to Node 2 (Value 4
).At Node 2 (Value 4
):
Node 2'
(Value 4
).Node 2'
after Node 2:
3 -> 3' -> 4 -> 4' -> 5 -> 7
.current
to Node 3 (Value 5
).At Node 3 (Value 5
):
Node 3'
(Value 5
).Node 3'
after Node 3:
3 -> 3' -> 4 -> 4' -> 5 -> 5' -> 7
.current
to Node 4 (Value 7
).At Node 4 (Value 7
):
Node 4'
(Value 7
).Node 4'
after Node 4:
3 -> 3' -> 4 -> 4' -> 5 -> 5' -> 7 -> 7'
.current
to null
, ending the first pass.Start with current
at Node 1 (Value 3
):
current.random
points to Node 2 (Value 4
).Node 1'.random
to Node 2'.random
:
Node 3'.random
is now correctly set to Node 2'.current
to Node 2 (Value 4
).At Node 2 (Value 4
):
current.random
is null
.Node 2'.random
remains null
.current
to Node 3 (Value 5
).At Node 3 (Value 5
):
current.random
points to Node 1 (Value 3
).Node 3'.random
to Node 1'.random
:
Node 3'.random
is now correctly set to Node 1'.current
to Node 4 (Value 7
).At Node 4 (Value 7
):
current.random
points to Node 3 (Value 5
).Node 4'.random
to Node 3'.random
:
Node 4'.random
is now correctly set to Node 3'.current
to null
, ending the second pass.Start with current
at Node 1 (Value 3
), copiedHead
at Node 1' (Value 3
), and copy
at Node 1'.
current.next
to Node 2 (restoring the original list).copy.next
to Node 2'.current
to Node 2 and copy
to Node 2'.At Node 2 (Value 4
):
current.next
to Node 3 (restoring the original list).copy.next
to Node 3'.current
to Node 3 and copy
to Node 3'.At Node 3 (Value 5
):
current.next
to Node 4 (restoring the original list).copy.next
to Node 4'.current
to Node 4 and copy
to Node 4'.At Node 4 (Value 7
):
current.next
to null
(restoring the original list).copy.next
to null
.current
to null
and copy
to null
, ending the third pass.3' -> 4' -> 5' -> 7'
, with correct next
and random
pointers.3 -> 4 -> 5 -> 7
.The time complexity of the solution is O(n), where n
is the number of nodes in the linked list. This is because we perform three passes over the list:
random
pointers for the copied nodes, which also takes O(n) time.The space complexity is O(1) (excluding the space required for the output). This is because we do not use any extra space proportional to the input size; we only manipulate the existing nodes to achieve the deep copy.
.....
.....
.....