|
| 1 | +--- |
| 2 | +id: copy-list-with-random-pointer |
| 3 | +title: Copy List with Random Pointer |
| 4 | +sidebar_label: 0138 Copy List with Random Pointer |
| 5 | +tags: |
| 6 | + - Java |
| 7 | + - Python |
| 8 | + - C++ |
| 9 | + - JavaScript |
| 10 | + |
| 11 | +description: "This is a solution to the Copy List with Random Pointer problem on LeetCode." |
| 12 | +--- |
| 13 | + |
| 14 | +## Problem Description |
| 15 | + |
| 16 | +A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or `null`. |
| 17 | + |
| 18 | +Construct a deep copy of the list. The deep copy should consist of exactly `n` brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the `next` and `random` pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list. |
| 19 | + |
| 20 | +For example, if there are two nodes `X` and `Y` in the original list, where `X.random --> Y`, then for the corresponding two nodes `x` and `y` in the copied list, `x.random --> y`. |
| 21 | + |
| 22 | +### Examples |
| 23 | + |
| 24 | +**Example 1:** |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +``` |
| 29 | +Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]] |
| 30 | +Output: [[7,null],[13,0],[11,4],[10,2],[1,0]] |
| 31 | +``` |
| 32 | + |
| 33 | +**Example 2:** |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +``` |
| 38 | +Input: head = [[1,1],[2,1]] |
| 39 | +Output: [[1,1],[2,1]] |
| 40 | +
|
| 41 | +``` |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +## Solution for Copy List with Random Pointer |
| 46 | + |
| 47 | + |
| 48 | +### Understand the Problem: |
| 49 | + |
| 50 | +Create a deep copy of a linked list where each node has a `next` and a `random` pointer. The new list should be identical in structure to the original, but with all new nodes. Ensure the `random` pointers in the new list accurately reflect the original's `random` pointer relationships. |
| 51 | + |
| 52 | +### Approach |
| 53 | + |
| 54 | +1. **Interweaving Nodes**: Create and insert new nodes immediately after each original node, forming an interwoven list. |
| 55 | +2. **Assigning Random Pointers**: Set the `random` pointers of the new nodes based on the `random` pointers of the original nodes. |
| 56 | +3. **Separating Lists**: Restore the original list and extract the copied list by adjusting the `next` pointers of both original and new nodes. |
| 57 | + |
| 58 | +#### Code in Different Languages |
| 59 | + |
| 60 | +<Tabs> |
| 61 | + |
| 62 | + |
| 63 | +<TabItem value="Python" label="Python" default> |
| 64 | + |
| 65 | + <SolutionAuthor name="sivaprasath2004"/> |
| 66 | + |
| 67 | + ```python |
| 68 | + |
| 69 | +class Node: |
| 70 | + def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): |
| 71 | + self.val = x |
| 72 | + self.next = next |
| 73 | + self.random = random |
| 74 | + |
| 75 | +def copyRandomList(head: 'Node') -> 'Node': |
| 76 | + if not head: |
| 77 | + return None |
| 78 | + |
| 79 | + current = head |
| 80 | + while current: |
| 81 | + new_node = Node(current.val, current.next, None) |
| 82 | + current.next = new_node |
| 83 | + current = new_node.next |
| 84 | + |
| 85 | + current = head |
| 86 | + while current: |
| 87 | + if current.random: |
| 88 | + current.next.random = current.random.next |
| 89 | + current = current.next.next |
| 90 | + |
| 91 | + original = head |
| 92 | + copy = head.next |
| 93 | + copy_head = copy |
| 94 | + |
| 95 | + while original: |
| 96 | + original.next = original.next.next |
| 97 | + if copy.next: |
| 98 | + copy.next = copy.next.next |
| 99 | + original = original.next |
| 100 | + copy = copy.next |
| 101 | + |
| 102 | + return copy_head |
| 103 | + |
| 104 | + ``` |
| 105 | + </TabItem> |
| 106 | + |
| 107 | + <TabItem value="Js" label="JavaScript" default> |
| 108 | + |
| 109 | + <SolutionAuthor name="sivaprasath2004"/> |
| 110 | + |
| 111 | + ```JS |
| 112 | +class Node { |
| 113 | + constructor(val, next = null, random = null) { |
| 114 | + this.val = val; |
| 115 | + this.next = next; |
| 116 | + this.random = random; |
| 117 | + } |
| 118 | +} |
| 119 | + |
| 120 | +function copyRandomList(head) { |
| 121 | + if (!head) return null; |
| 122 | + |
| 123 | + let current = head; |
| 124 | + while (current) { |
| 125 | + const newNode = new Node(current.val); |
| 126 | + newNode.next = current.next; |
| 127 | + current.next = newNode; |
| 128 | + current = newNode.next; |
| 129 | + } |
| 130 | + |
| 131 | + current = head; |
| 132 | + while (current) { |
| 133 | + if (current.random) { |
| 134 | + current.next.random = current.random.next; |
| 135 | + } |
| 136 | + current = current.next.next; |
| 137 | + } |
| 138 | + current = head; |
| 139 | + const newHead = head.next; |
| 140 | + let copyCurrent = newHead; |
| 141 | + |
| 142 | + while (current) { |
| 143 | + current.next = current.next.next; |
| 144 | + if (copyCurrent.next) { |
| 145 | + copyCurrent.next = copyCurrent.next.next; |
| 146 | + } |
| 147 | + current = current.next; |
| 148 | + copyCurrent = copyCurrent.next; |
| 149 | + } |
| 150 | + |
| 151 | + return newHead; |
| 152 | +} |
| 153 | + |
| 154 | +``` |
| 155 | + </TabItem> |
| 156 | + |
| 157 | + </Tabs> |
| 158 | + |
| 159 | + |
| 160 | +### Output |
| 161 | + |
| 162 | + |
| 163 | + |
| 164 | +### Complexity |
| 165 | + |
| 166 | +- **Time Complexity:** O(n), where `n` is the number of nodes in the linked list. The algorithm iterates through the list three times: once for interweaving nodes, once for setting random pointers, and once for separating the lists. |
| 167 | + |
| 168 | +- **Space Complexity:** O(1), since the algorithm uses a constant amount of extra space beyond the input list itself (e.g., pointers for traversal and temporary variables). |
| 169 | + |
0 commit comments