|
7 | 7 | 4. 地點: google meet 線上 (前 10 分鐘預備鏈接)
|
8 | 8 | 5. 解題項目: [Linked list](https://leetcode.com/explore/learn/card/linked-list/210/doubly-linked-list/)
|
9 | 9 |
|
10 |
| - ```text、 |
| 10 | +```text |
11 | 11 | 5. Medium 138. Copy List with Random Pointer
|
12 | 12 | > Hint: Using a hash set maybe is a good idea. Refer to our hash table card if you are not familiar with the hash set.
|
13 | 13 | 6. Medium 61. Rotate List
|
14 | 14 | > Come up with as many solutions as you can.
|
15 | 15 |
|
16 | 16 |
|
17 |
| - ``` |
| 17 | +``` |
18 | 18 |
|
19 | 19 | 6. 共筆: GitHub https://github.com/programmingbookclub/Leetcode-club
|
| 20 | + |
| 21 | + # Copy List with Random Pointer |
| 22 | + |
| 23 | +Solution |
| 24 | +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. |
| 25 | + |
| 26 | +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. |
| 27 | + |
| 28 | +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. |
| 29 | + |
| 30 | +Return the head of the copied linked list. |
| 31 | + |
| 32 | +The linked list is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where: |
| 33 | + |
| 34 | +val: an integer representing Node.val |
| 35 | +random_index: 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. |
| 36 | +Your code will only be given the head of the original linked list. |
| 37 | + |
| 38 | + |
| 39 | +```java= |
| 40 | +// Java recursion |
| 41 | +/* |
| 42 | +// Definition for a Node. |
| 43 | +class Node { |
| 44 | + public int val; |
| 45 | + public Node next; |
| 46 | + public Node random; |
| 47 | +
|
| 48 | + public Node() {} |
| 49 | +
|
| 50 | + public Node(int _val,Node _next,Node _random) { |
| 51 | + val = _val; |
| 52 | + next = _next; |
| 53 | + random = _random; |
| 54 | + } |
| 55 | +}; |
| 56 | +*/ |
| 57 | +public class Solution { |
| 58 | + // HashMap which holds old nodes as keys and new nodes as its values. |
| 59 | + HashMap<Node, Node> visitedHash = new HashMap<Node, Node>(); |
| 60 | +
|
| 61 | + public Node copyRandomList(Node head) { |
| 62 | +
|
| 63 | + if (head == null) { |
| 64 | + return null; |
| 65 | + } |
| 66 | +
|
| 67 | + // If we have already processed the current node, then we simply return the cloned version of |
| 68 | + // it. |
| 69 | + if (this.visitedHash.containsKey(head)) { |
| 70 | + return this.visitedHash.get(head); |
| 71 | + } |
| 72 | +
|
| 73 | + // Create a new node with the value same as old node. (i.e. copy the node) |
| 74 | + Node node = new Node(head.val, null, null); |
| 75 | +
|
| 76 | + // Save this value in the hash map. This is needed since there might be |
| 77 | + // loops during traversal due to randomness of random pointers and this would help us avoid |
| 78 | + // them. |
| 79 | + this.visitedHash.put(head, node); |
| 80 | +
|
| 81 | + // Recursively copy the remaining linked list starting once from the next pointer and then from |
| 82 | + // the random pointer. |
| 83 | + // Thus we have two independent recursive calls. |
| 84 | + // Finally we update the next and random pointers for the new node created. |
| 85 | + node.next = this.copyRandomList(head.next); |
| 86 | + node.random = this.copyRandomList(head.random); |
| 87 | +
|
| 88 | + return node; |
| 89 | + } |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +```java= |
| 94 | +// JAVA |
| 95 | +// Iterative |
| 96 | +/* |
| 97 | +// Definition for a Node. |
| 98 | +class Node { |
| 99 | + public int val; |
| 100 | + public Node next; |
| 101 | + public Node random; |
| 102 | +
|
| 103 | + public Node() {} |
| 104 | +
|
| 105 | + public Node(int _val,Node _next,Node _random) { |
| 106 | + val = _val; |
| 107 | + next = _next; |
| 108 | + random = _random; |
| 109 | + } |
| 110 | +}; |
| 111 | +*/ |
| 112 | +public class Solution { |
| 113 | + // Visited dictionary to hold old node reference as "key" and new node reference as the "value" |
| 114 | + HashMap<Node, Node> visited = new HashMap<Node, Node>(); |
| 115 | +
|
| 116 | + public Node getClonedNode(Node node) { |
| 117 | + // If the node exists then |
| 118 | + if (node != null) { |
| 119 | + // Check if the node is in the visited dictionary |
| 120 | + if (this.visited.containsKey(node)) { |
| 121 | + // If its in the visited dictionary then return the new node reference from the dictionary |
| 122 | + return this.visited.get(node); |
| 123 | + } else { |
| 124 | + // Otherwise create a new node, add to the dictionary and return it |
| 125 | + this.visited.put(node, new Node(node.val, null, null)); |
| 126 | + return this.visited.get(node); |
| 127 | + } |
| 128 | + } |
| 129 | + return null; |
| 130 | + } |
| 131 | +
|
| 132 | + public Node copyRandomList(Node head) { |
| 133 | +
|
| 134 | + if (head == null) { |
| 135 | + return null; |
| 136 | + } |
| 137 | +
|
| 138 | + Node oldNode = head; |
| 139 | +
|
| 140 | + // Creating the new head node. |
| 141 | + Node newNode = new Node(oldNode.val); |
| 142 | + this.visited.put(oldNode, newNode); |
| 143 | +
|
| 144 | + // Iterate on the linked list until all nodes are cloned. |
| 145 | + while (oldNode != null) { |
| 146 | + // Get the clones of the nodes referenced by random and next pointers. |
| 147 | + newNode.random = this.getClonedNode(oldNode.random); |
| 148 | + newNode.next = this.getClonedNode(oldNode.next); |
| 149 | +
|
| 150 | + // Move one step ahead in the linked list. |
| 151 | + oldNode = oldNode.next; |
| 152 | + newNode = newNode.next; |
| 153 | + } |
| 154 | + return this.visited.get(head); |
| 155 | + } |
| 156 | +} |
| 157 | +``` |
| 158 | + |
| 159 | +```text |
| 160 | +[[7,null],[13,0],[11,4],[10,2],[1,0]] |
| 161 | +[[7,null],[7',null],[13,0],[13, 0],[11,4],[11,4],[10,2],[10,2], [1,0], [1,0]] |
| 162 | +[[7',null],[13',0.next],[11',4.next],[10',2.next],[1',0.next]] |
| 163 | +``` |
| 164 | +* 下面的解法會破壞原linked list的結構,正確的解法是中間再多一個while來指定每個新node的random |
| 165 | +```python= |
| 166 | +""" |
| 167 | +# Definition for a Node. |
| 168 | +class Node: |
| 169 | + def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): |
| 170 | + self.val = int(x) |
| 171 | + self.next = next |
| 172 | + self.random = random |
| 173 | +""" |
| 174 | +
|
| 175 | +class Solution: |
| 176 | + def copyRandomList(self, head: 'Node') -> 'Node': |
| 177 | + if not head: |
| 178 | + return head |
| 179 | + hash_table = {} |
| 180 | + dummy = head |
| 181 | + while(head): |
| 182 | + clone_node = Node(head.val, head.next, head.random) |
| 183 | + head.next = clone_node |
| 184 | + head = head.next.next |
| 185 | + head = dummy |
| 186 | + while(head): |
| 187 | + next = head.next.next |
| 188 | + old = head |
| 189 | + new = head.next |
| 190 | + if new.next: |
| 191 | + new.next = new.next.next |
| 192 | + else: |
| 193 | + new.next = None |
| 194 | + if old.random: |
| 195 | + new.random = old.random.next |
| 196 | + else: |
| 197 | + new.random = None |
| 198 | + head = next |
| 199 | + return dummy.next |
| 200 | +``` |
0 commit comments