From e7718b804614d2e1c025f18d63f43d45a4f4adf2 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 30 Dec 2024 17:16:37 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0138 No.0138.Copy List with Random Pointer --- .../README.md | 22 -- .../README_EN.md | 22 -- .../Solution2.cpp | 7 - .../README.md | 332 ++++++++++-------- .../README_EN.md | 330 ++++++++++------- .../Solution.cpp | 20 +- .../Solution.cs | 16 +- .../Solution.go | 17 +- .../Solution.java | 14 +- .../Solution.js | 21 +- .../Solution.py | 11 +- .../Solution.ts | 35 +- .../Solution2.cpp | 25 +- .../Solution2.cs | 25 +- .../Solution2.go | 12 +- .../Solution2.java | 30 +- .../Solution2.js | 35 +- .../Solution2.py | 18 +- .../Solution2.ts | 40 +++ 19 files changed, 567 insertions(+), 465 deletions(-) delete mode 100644 solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp create mode 100644 solution/0100-0199/0138.Copy List with Random Pointer/Solution2.ts diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md index dda26e8bdaea5..fdb81fb61551c 100644 --- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md +++ b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README.md @@ -250,26 +250,4 @@ class Solution { - - -### 方法二 - - - -#### C++ - -```cpp -class Solution { -public: - int removeDuplicates(vector& nums) { - nums.erase(unique(nums.begin(), nums.end()), nums.end()); - return nums.size(); - } -}; -``` - - - - - diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md index 8ac890d1cd1c5..1cdc125638954 100644 --- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md +++ b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/README_EN.md @@ -251,26 +251,4 @@ class Solution { - - -### Solution 2 - - - -#### C++ - -```cpp -class Solution { -public: - int removeDuplicates(vector& nums) { - nums.erase(unique(nums.begin(), nums.end()), nums.end()); - return nums.size(); - } -}; -``` - - - - - diff --git a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp b/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp deleted file mode 100644 index c1cdf93285b2c..0000000000000 --- a/solution/0000-0099/0026.Remove Duplicates from Sorted Array/Solution2.cpp +++ /dev/null @@ -1,7 +0,0 @@ -class Solution { -public: - int removeDuplicates(vector& nums) { - nums.erase(unique(nums.begin(), nums.end()), nums.end()); - return nums.size(); - } -}; \ No newline at end of file diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/README.md b/solution/0100-0199/0138.Copy List with Random Pointer/README.md index 14c4805dae32f..02ef9db7b6ae1 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/README.md +++ b/solution/0100-0199/0138.Copy List with Random Pointer/README.md @@ -81,13 +81,13 @@ tags: -### 方法一:哈希表 +### 方法一:哈希表 + 模拟 -遍历链表,将链表中的每个节点都复制一份,然后将原节点和复制节点的对应关系存储在哈希表中,同时连接好复制节点的 $next$ 指针。 +我们可以定义一个虚拟头节点 $\textit{dummy}$,用一个指针 $\textit{tail}$ 指向虚拟头节点,然后遍历链表,将链表中的每个节点都复制一份,并将每个节点及其复制节点的对应关系存储在哈希表 $\textit{d}$ 中,同时连接好复制节点的 $\textit{next}$ 指针。 -接下来再遍历链表,根据哈希表中存储的对应关系,将复制节点的 $random$ 指针连接好。 +接下来再遍历链表,根据哈希表中存储的对应关系,将复制节点的 $\textit{random}$ 指针连接好。 -时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。其中 $n$ 为链表的长度。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为链表的长度。 @@ -105,20 +105,19 @@ class Node: class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": d = {} dummy = tail = Node(0) cur = head while cur: - tail.next = Node(cur.val) + node = Node(cur.val) + tail.next = node tail = tail.next - d[cur] = tail + d[cur] = node cur = cur.next - tail = dummy.next cur = head while cur: - tail.random = d.get(cur.random) - tail = tail.next + d[cur].random = d[cur.random] if cur.random else None cur = cur.next return dummy.next ``` @@ -140,20 +139,20 @@ class Node { } } */ + class Solution { public Node copyRandomList(Node head) { Map d = new HashMap<>(); Node dummy = new Node(0); Node tail = dummy; for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.put(cur, tail); + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d.put(cur, node); } - tail = dummy.next; for (Node cur = head; cur != null; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random == null ? null : d.get(cur.random); } return dummy.next; } @@ -178,21 +177,21 @@ public: } }; */ + class Solution { public: Node* copyRandomList(Node* head) { - unordered_map d; Node* dummy = new Node(0); Node* tail = dummy; - for (auto cur = head; cur; cur = cur->next) { - tail->next = new Node(cur->val); - tail = tail->next; - d[cur] = tail; + unordered_map d; + for (Node* cur = head; cur; cur = cur->next) { + Node* node = new Node(cur->val); + tail->next = node; + tail = node; + d[cur] = node; } - tail = dummy->next; - for (auto cur = head; cur; cur = cur->next) { - tail->random = d[cur->random]; - tail = tail->next; + for (Node* cur = head; cur; cur = cur->next) { + d[cur]->random = cur->random ? d[cur->random] : nullptr; } return dummy->next; } @@ -212,18 +211,19 @@ public: */ func copyRandomList(head *Node) *Node { - d := map[*Node]*Node{} dummy := &Node{} tail := dummy + d := map[*Node]*Node{} for cur := head; cur != nil; cur = cur.Next { - tail.Next = &Node{Val: cur.Val} - tail = tail.Next - d[cur] = tail + node := &Node{Val: cur.Val} + d[cur] = node + tail.Next = node + tail = node } - tail = dummy.Next for cur := head; cur != nil; cur = cur.Next { - tail.Random = d[cur.Random] - tail = tail.Next + if cur.Random != nil { + d[cur].Random = d[cur.Random] + } } return dummy.Next } @@ -233,12 +233,13 @@ func copyRandomList(head *Node) *Node { ```ts /** - * Definition for Node. - * class Node { + * Definition for _Node. + * class _Node { * val: number - * next: Node | null - * random: Node | null - * constructor(val?: number, next?: Node, random?: Node) { + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * this.random = (random===undefined ? null : random) @@ -246,20 +247,20 @@ func copyRandomList(head *Node) *Node { * } */ -function copyRandomList(head: Node | null): Node | null { - const map = new Map(); - let cur = head; - while (cur != null) { - map.set(cur, new Node(cur.val)); - cur = cur.next; +function copyRandomList(head: _Node | null): _Node | null { + const d: Map<_Node, _Node> = new Map(); + const dummy = new _Node(); + let tail = dummy; + for (let cur = head; cur; cur = cur.next) { + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - cur = head; - while (cur != null) { - map.get(cur).next = map.get(cur.next) ?? null; - map.get(cur).random = map.get(cur.random) ?? null; - cur = cur.next; + for (let cur = head; cur; cur = cur.next) { + d.get(cur)!.random = cur.random ? d.get(cur.random)! : null; } - return map.get(head); + return dummy.next; } ``` @@ -267,8 +268,8 @@ function copyRandomList(head: Node | null): Node | null { ```js /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -276,22 +277,21 @@ function copyRandomList(head: Node | null): Node | null { */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { const d = new Map(); - const dummy = new Node(0); + const dummy = new _Node(); let tail = dummy; for (let cur = head; cur; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.set(cur, tail); + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - tail = dummy.next; for (let cur = head; cur; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random ? d.get(cur.random) : null; } return dummy.next; }; @@ -320,16 +320,20 @@ public class Solution { Dictionary d = new Dictionary(); Node dummy = new Node(0); Node tail = dummy; + for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d[cur] = tail; + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d[cur] = node; } - tail = dummy.next; + for (Node cur = head; cur != null; cur = cur.next) { - tail.random = cur.random == null ? null : d[cur.random]; - tail = tail.next; + if (cur.random != null) { + d[cur].random = d[cur.random]; + } } + return dummy.next; } } @@ -341,15 +345,15 @@ public class Solution { -### 方法二:拼接 + 拆分 - -遍历链表,将链表中的每个节点都复制一份,然后将复制节点插入到原节点的后面。 +### 方法二:模拟(空间优化) -接下来再遍历链表,根据原节点的 $random$ 指针,将复制节点的 $random$ 指针连接好。 +在方法一中,我们使用了额外的哈希表来存储原节点和复制节点的对应关系,我们也可以不使用额外的空间,具体做法如下: -最后再遍历链表,将链表拆分成原链表和复制链表。 +1. 遍历原链表,对于每个节点,复制一个新节点并将其插入到原节点和原节点的下一个节点之间。 +2. 再次遍历链表,根据原节点的 $\textit{random}$ 指针,设置新节点的 $\textit{random}$ 指针。 +3. 最后将链表拆分为原链表和复制链表。 -时间复杂度为 $O(n)$,空间复杂度为 $O(1)$。其中 $n$ 为链表的长度。 +时间复杂度 $O(n)$,其中 $n$ 为链表的长度。忽略答案链表的空间占用,空间复杂度 $O(1)$。 @@ -367,7 +371,7 @@ class Node: class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": if head is None: return None cur = head @@ -375,20 +379,16 @@ class Solution: node = Node(cur.val, cur.next) cur.next = node cur = node.next - cur = head while cur: - if cur.random: - cur.next.random = cur.random.next + cur.next.random = cur.random.next if cur.random else None cur = cur.next.next - - ans = head.next cur = head - while cur: - nxt = cur.next - if nxt: - cur.next = nxt.next - cur = nxt + ans = head.next + while cur.next: + node = cur.next + cur.next = node.next + cur = node return ans ``` @@ -409,28 +409,30 @@ class Node { } } */ -class Solution { + +public class Solution { public Node copyRandomList(Node head) { if (head == null) { return null; } - for (Node cur = head; cur != null;) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null;) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } @@ -455,30 +457,31 @@ public: } }; */ + class Solution { public: Node* copyRandomList(Node* head) { if (!head) { return nullptr; } - for (Node* cur = head; cur;) { + Node* cur = head; + while (cur != nullptr) { Node* node = new Node(cur->val); node->next = cur->next; cur->next = node; cur = node->next; } - for (Node* cur = head; cur; cur = cur->next->next) { - if (cur->random) { - cur->next->random = cur->random->next; - } + cur = head; + while (cur != nullptr) { + cur->next->random = cur->random == nullptr ? nullptr : cur->random->next; + cur = cur->next->next; } + cur = head; Node* ans = head->next; - for (Node* cur = head; cur;) { - Node* nxt = cur->next; - if (nxt) { - cur->next = nxt->next; - } - cur = nxt; + while (cur->next != nullptr) { + Node* node = cur->next; + cur->next = node->next; + cur = node; } return ans; } @@ -512,23 +515,66 @@ func copyRandomList(head *Node) *Node { } } ans := head.Next - for cur := head; cur != nil; { - nxt := cur.Next - if nxt != nil { - cur.Next = nxt.Next - } - cur = nxt + for cur := head; cur.Next != nil; { + node := cur.Next + cur.Next = node.Next + cur = node } return ans } ``` +#### TypeScript + +```ts +/** + * Definition for _Node. + * class _Node { + * val: number + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * this.random = (random===undefined ? null : random) + * } + * } + */ + +function copyRandomList(head: _Node | null): _Node | null { + if (head === null) { + return null; + } + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; + cur.next = node; + cur = node.next; + } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; + } + cur = head; + const ans = head.next; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; + } + return ans; +} +``` + #### JavaScript ```js /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -536,30 +582,31 @@ func copyRandomList(head *Node) *Node { */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { - if (!head) { + if (head === null) { return null; } - for (let cur = head; cur; ) { - const node = new Node(cur.val, cur.next, null); + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (let cur = head; cur; cur = cur.next.next) { - if (cur.random) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; const ans = head.next; - for (let cur = head; cur; ) { - const nxt = cur.next; - if (nxt) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; } return ans; }; @@ -588,23 +635,24 @@ public class Solution { if (head == null) { return null; } - for (Node cur = head; cur != null; ) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null; ) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/README_EN.md b/solution/0100-0199/0138.Copy List with Random Pointer/README_EN.md index 00d08b60ccb7e..52378a99a2ef0 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/README_EN.md +++ b/solution/0100-0199/0138.Copy List with Random Pointer/README_EN.md @@ -73,7 +73,13 @@ tags: -### Solution 1 +### Solution 1: Hash Table + +We can define a dummy head node $\textit{dummy}$ and use a pointer $\textit{tail}$ to point to the dummy head node. Then, we traverse the linked list, copying each node and storing the mapping between each node and its copy in a hash table $\textit{d}$, while also connecting the $\textit{next}$ pointers of the copied nodes. + +Next, we traverse the linked list again and use the mappings stored in the hash table to connect the $\textit{random}$ pointers of the copied nodes. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the linked list. @@ -91,20 +97,19 @@ class Node: class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": d = {} dummy = tail = Node(0) cur = head while cur: - tail.next = Node(cur.val) + node = Node(cur.val) + tail.next = node tail = tail.next - d[cur] = tail + d[cur] = node cur = cur.next - tail = dummy.next cur = head while cur: - tail.random = d.get(cur.random) - tail = tail.next + d[cur].random = d[cur.random] if cur.random else None cur = cur.next return dummy.next ``` @@ -126,20 +131,20 @@ class Node { } } */ + class Solution { public Node copyRandomList(Node head) { Map d = new HashMap<>(); Node dummy = new Node(0); Node tail = dummy; for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.put(cur, tail); + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d.put(cur, node); } - tail = dummy.next; for (Node cur = head; cur != null; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random == null ? null : d.get(cur.random); } return dummy.next; } @@ -164,21 +169,21 @@ public: } }; */ + class Solution { public: Node* copyRandomList(Node* head) { - unordered_map d; Node* dummy = new Node(0); Node* tail = dummy; - for (auto cur = head; cur; cur = cur->next) { - tail->next = new Node(cur->val); - tail = tail->next; - d[cur] = tail; + unordered_map d; + for (Node* cur = head; cur; cur = cur->next) { + Node* node = new Node(cur->val); + tail->next = node; + tail = node; + d[cur] = node; } - tail = dummy->next; - for (auto cur = head; cur; cur = cur->next) { - tail->random = d[cur->random]; - tail = tail->next; + for (Node* cur = head; cur; cur = cur->next) { + d[cur]->random = cur->random ? d[cur->random] : nullptr; } return dummy->next; } @@ -198,18 +203,19 @@ public: */ func copyRandomList(head *Node) *Node { - d := map[*Node]*Node{} dummy := &Node{} tail := dummy + d := map[*Node]*Node{} for cur := head; cur != nil; cur = cur.Next { - tail.Next = &Node{Val: cur.Val} - tail = tail.Next - d[cur] = tail + node := &Node{Val: cur.Val} + d[cur] = node + tail.Next = node + tail = node } - tail = dummy.Next for cur := head; cur != nil; cur = cur.Next { - tail.Random = d[cur.Random] - tail = tail.Next + if cur.Random != nil { + d[cur].Random = d[cur.Random] + } } return dummy.Next } @@ -219,12 +225,13 @@ func copyRandomList(head *Node) *Node { ```ts /** - * Definition for Node. - * class Node { + * Definition for _Node. + * class _Node { * val: number - * next: Node | null - * random: Node | null - * constructor(val?: number, next?: Node, random?: Node) { + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * this.random = (random===undefined ? null : random) @@ -232,20 +239,20 @@ func copyRandomList(head *Node) *Node { * } */ -function copyRandomList(head: Node | null): Node | null { - const map = new Map(); - let cur = head; - while (cur != null) { - map.set(cur, new Node(cur.val)); - cur = cur.next; +function copyRandomList(head: _Node | null): _Node | null { + const d: Map<_Node, _Node> = new Map(); + const dummy = new _Node(); + let tail = dummy; + for (let cur = head; cur; cur = cur.next) { + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - cur = head; - while (cur != null) { - map.get(cur).next = map.get(cur.next) ?? null; - map.get(cur).random = map.get(cur.random) ?? null; - cur = cur.next; + for (let cur = head; cur; cur = cur.next) { + d.get(cur)!.random = cur.random ? d.get(cur.random)! : null; } - return map.get(head); + return dummy.next; } ``` @@ -253,8 +260,8 @@ function copyRandomList(head: Node | null): Node | null { ```js /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -262,22 +269,21 @@ function copyRandomList(head: Node | null): Node | null { */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { const d = new Map(); - const dummy = new Node(0); + const dummy = new _Node(); let tail = dummy; for (let cur = head; cur; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.set(cur, tail); + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - tail = dummy.next; for (let cur = head; cur; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random ? d.get(cur.random) : null; } return dummy.next; }; @@ -306,16 +312,20 @@ public class Solution { Dictionary d = new Dictionary(); Node dummy = new Node(0); Node tail = dummy; + for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d[cur] = tail; + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d[cur] = node; } - tail = dummy.next; + for (Node cur = head; cur != null; cur = cur.next) { - tail.random = cur.random == null ? null : d[cur.random]; - tail = tail.next; + if (cur.random != null) { + d[cur].random = d[cur.random]; + } } + return dummy.next; } } @@ -327,7 +337,15 @@ public class Solution { -### Solution 2 +### Solution 2: Simulation (Space Optimization) + +In Solution 1, we used an additional hash table to store the mapping between the original nodes and the copied nodes. We can also achieve this without using extra space, as follows: + +1. Traverse the original linked list, and for each node, create a new node and insert it between the original node and the original node's next node. +2. Traverse the linked list again, and set the $\textit{random}$ pointer of the new node based on the $\textit{random}$ pointer of the original node. +3. Finally, split the linked list into the original linked list and the copied linked list. + +The time complexity is $O(n)$, where $n$ is the length of the linked list. Ignoring the space occupied by the answer linked list, the space complexity is $O(1)$. @@ -345,7 +363,7 @@ class Node: class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": if head is None: return None cur = head @@ -353,20 +371,16 @@ class Solution: node = Node(cur.val, cur.next) cur.next = node cur = node.next - cur = head while cur: - if cur.random: - cur.next.random = cur.random.next + cur.next.random = cur.random.next if cur.random else None cur = cur.next.next - - ans = head.next cur = head - while cur: - nxt = cur.next - if nxt: - cur.next = nxt.next - cur = nxt + ans = head.next + while cur.next: + node = cur.next + cur.next = node.next + cur = node return ans ``` @@ -387,28 +401,30 @@ class Node { } } */ -class Solution { + +public class Solution { public Node copyRandomList(Node head) { if (head == null) { return null; } - for (Node cur = head; cur != null;) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null;) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } @@ -433,30 +449,31 @@ public: } }; */ + class Solution { public: Node* copyRandomList(Node* head) { if (!head) { return nullptr; } - for (Node* cur = head; cur;) { + Node* cur = head; + while (cur != nullptr) { Node* node = new Node(cur->val); node->next = cur->next; cur->next = node; cur = node->next; } - for (Node* cur = head; cur; cur = cur->next->next) { - if (cur->random) { - cur->next->random = cur->random->next; - } + cur = head; + while (cur != nullptr) { + cur->next->random = cur->random == nullptr ? nullptr : cur->random->next; + cur = cur->next->next; } + cur = head; Node* ans = head->next; - for (Node* cur = head; cur;) { - Node* nxt = cur->next; - if (nxt) { - cur->next = nxt->next; - } - cur = nxt; + while (cur->next != nullptr) { + Node* node = cur->next; + cur->next = node->next; + cur = node; } return ans; } @@ -490,23 +507,66 @@ func copyRandomList(head *Node) *Node { } } ans := head.Next - for cur := head; cur != nil; { - nxt := cur.Next - if nxt != nil { - cur.Next = nxt.Next - } - cur = nxt + for cur := head; cur.Next != nil; { + node := cur.Next + cur.Next = node.Next + cur = node } return ans } ``` +#### TypeScript + +```ts +/** + * Definition for _Node. + * class _Node { + * val: number + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * this.random = (random===undefined ? null : random) + * } + * } + */ + +function copyRandomList(head: _Node | null): _Node | null { + if (head === null) { + return null; + } + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; + cur.next = node; + cur = node.next; + } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; + } + cur = head; + const ans = head.next; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; + } + return ans; +} +``` + #### JavaScript ```js /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -514,30 +574,31 @@ func copyRandomList(head *Node) *Node { */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { - if (!head) { + if (head === null) { return null; } - for (let cur = head; cur; ) { - const node = new Node(cur.val, cur.next, null); + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (let cur = head; cur; cur = cur.next.next) { - if (cur.random) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; const ans = head.next; - for (let cur = head; cur; ) { - const nxt = cur.next; - if (nxt) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; } return ans; }; @@ -566,23 +627,24 @@ public class Solution { if (head == null) { return null; } - for (Node cur = head; cur != null; ) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null; ) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cpp b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cpp index 48858e8ac32bd..826b203a01776 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cpp +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cpp @@ -13,22 +13,22 @@ class Node { } }; */ + class Solution { public: Node* copyRandomList(Node* head) { - unordered_map d; Node* dummy = new Node(0); Node* tail = dummy; - for (auto cur = head; cur; cur = cur->next) { - tail->next = new Node(cur->val); - tail = tail->next; - d[cur] = tail; + unordered_map d; + for (Node* cur = head; cur; cur = cur->next) { + Node* node = new Node(cur->val); + tail->next = node; + tail = node; + d[cur] = node; } - tail = dummy->next; - for (auto cur = head; cur; cur = cur->next) { - tail->random = d[cur->random]; - tail = tail->next; + for (Node* cur = head; cur; cur = cur->next) { + d[cur]->random = cur->random ? d[cur->random] : nullptr; } return dummy->next; } -}; \ No newline at end of file +}; diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cs b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cs index 97a43f56c2934..232b4d185c9c9 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cs +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.cs @@ -18,16 +18,20 @@ public Node CopyRandomList(Node head) { Dictionary d = new Dictionary(); Node dummy = new Node(0); Node tail = dummy; + for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d[cur] = tail; + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d[cur] = node; } - tail = dummy.next; + for (Node cur = head; cur != null; cur = cur.next) { - tail.random = cur.random == null ? null : d[cur.random]; - tail = tail.next; + if (cur.random != null) { + d[cur].random = d[cur.random]; + } } + return dummy.next; } } diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.go b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.go index 08ed594b862b9..d67c5cf14657d 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.go +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.go @@ -8,18 +8,19 @@ */ func copyRandomList(head *Node) *Node { - d := map[*Node]*Node{} dummy := &Node{} tail := dummy + d := map[*Node]*Node{} for cur := head; cur != nil; cur = cur.Next { - tail.Next = &Node{Val: cur.Val} - tail = tail.Next - d[cur] = tail + node := &Node{Val: cur.Val} + d[cur] = node + tail.Next = node + tail = node } - tail = dummy.Next for cur := head; cur != nil; cur = cur.Next { - tail.Random = d[cur.Random] - tail = tail.Next + if cur.Random != nil { + d[cur].Random = d[cur.Random] + } } return dummy.Next -} \ No newline at end of file +} diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.java b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.java index 2bce78d217257..89d0a9c809154 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.java +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.java @@ -12,21 +12,21 @@ public Node(int val) { } } */ + class Solution { public Node copyRandomList(Node head) { Map d = new HashMap<>(); Node dummy = new Node(0); Node tail = dummy; for (Node cur = head; cur != null; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.put(cur, tail); + Node node = new Node(cur.val); + tail.next = node; + tail = node; + d.put(cur, node); } - tail = dummy.next; for (Node cur = head; cur != null; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random == null ? null : d.get(cur.random); } return dummy.next; } -} \ No newline at end of file +} diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.js b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.js index b7cd78df5c464..f76a9916eb4f4 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.js +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.js @@ -1,6 +1,6 @@ /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -8,22 +8,21 @@ */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { const d = new Map(); - const dummy = new Node(0); + const dummy = new _Node(); let tail = dummy; for (let cur = head; cur; cur = cur.next) { - tail.next = new Node(cur.val); - tail = tail.next; - d.set(cur, tail); + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - tail = dummy.next; for (let cur = head; cur; cur = cur.next) { - tail.random = d.get(cur.random); - tail = tail.next; + d.get(cur).random = cur.random ? d.get(cur.random) : null; } return dummy.next; }; diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.py b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.py index 57797589c37c6..d1a644a2b2733 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.py +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.py @@ -9,19 +9,18 @@ def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": d = {} dummy = tail = Node(0) cur = head while cur: - tail.next = Node(cur.val) + node = Node(cur.val) + tail.next = node tail = tail.next - d[cur] = tail + d[cur] = node cur = cur.next - tail = dummy.next cur = head while cur: - tail.random = d.get(cur.random) - tail = tail.next + d[cur].random = d[cur.random] if cur.random else None cur = cur.next return dummy.next diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.ts b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.ts index 15edae01d2f82..e61ffa0c4e88a 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution.ts +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution.ts @@ -1,10 +1,11 @@ /** - * Definition for Node. - * class Node { + * Definition for _Node. + * class _Node { * val: number - * next: Node | null - * random: Node | null - * constructor(val?: number, next?: Node, random?: Node) { + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * this.random = (random===undefined ? null : random) @@ -12,18 +13,18 @@ * } */ -function copyRandomList(head: Node | null): Node | null { - const map = new Map(); - let cur = head; - while (cur != null) { - map.set(cur, new Node(cur.val)); - cur = cur.next; +function copyRandomList(head: _Node | null): _Node | null { + const d: Map<_Node, _Node> = new Map(); + const dummy = new _Node(); + let tail = dummy; + for (let cur = head; cur; cur = cur.next) { + const node = new _Node(cur.val); + tail.next = node; + tail = node; + d.set(cur, node); } - cur = head; - while (cur != null) { - map.get(cur).next = map.get(cur.next) ?? null; - map.get(cur).random = map.get(cur.random) ?? null; - cur = cur.next; + for (let cur = head; cur; cur = cur.next) { + d.get(cur)!.random = cur.random ? d.get(cur.random)! : null; } - return map.get(head); + return dummy.next; } diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cpp b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cpp index a98a121581a14..e62e2922d7225 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cpp +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cpp @@ -13,31 +13,32 @@ class Node { } }; */ + class Solution { public: Node* copyRandomList(Node* head) { if (!head) { return nullptr; } - for (Node* cur = head; cur;) { + Node* cur = head; + while (cur != nullptr) { Node* node = new Node(cur->val); node->next = cur->next; cur->next = node; cur = node->next; } - for (Node* cur = head; cur; cur = cur->next->next) { - if (cur->random) { - cur->next->random = cur->random->next; - } + cur = head; + while (cur != nullptr) { + cur->next->random = cur->random == nullptr ? nullptr : cur->random->next; + cur = cur->next->next; } + cur = head; Node* ans = head->next; - for (Node* cur = head; cur;) { - Node* nxt = cur->next; - if (nxt) { - cur->next = nxt->next; - } - cur = nxt; + while (cur->next != nullptr) { + Node* node = cur->next; + cur->next = node->next; + cur = node; } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cs b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cs index c05d1da4a1065..75e46e06fb3e6 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cs +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.cs @@ -18,23 +18,24 @@ public Node CopyRandomList(Node head) { if (head == null) { return null; } - for (Node cur = head; cur != null; ) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null; ) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.go b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.go index 8039efadcbe65..410ee693ad823 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.go +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.go @@ -22,12 +22,10 @@ func copyRandomList(head *Node) *Node { } } ans := head.Next - for cur := head; cur != nil; { - nxt := cur.Next - if nxt != nil { - cur.Next = nxt.Next - } - cur = nxt + for cur := head; cur.Next != nil; { + node := cur.Next + cur.Next = node.Next + cur = node } return ans -} \ No newline at end of file +} diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.java b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.java index 9ed0bdedf01f1..4e6f88bbdb355 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.java +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.java @@ -12,29 +12,31 @@ public Node(int val) { } } */ -class Solution { + +public class Solution { public Node copyRandomList(Node head) { if (head == null) { return null; } - for (Node cur = head; cur != null;) { - Node node = new Node(cur.val, cur.next); + Node cur = head; + while (cur != null) { + Node node = new Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (Node cur = head; cur != null; cur = cur.next.next) { - if (cur.random != null) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; Node ans = head.next; - for (Node cur = head; cur != null;) { - Node nxt = cur.next; - if (nxt != null) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next != null) { + Node node = cur.next; + cur.next = node.next; + cur = node; } return ans; } -} \ No newline at end of file +} diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.js b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.js index 93fd2cf31a78b..e6b39fa0fdad8 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.js +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.js @@ -1,6 +1,6 @@ /** - * // Definition for a Node. - * function Node(val, next, random) { + * // Definition for a _Node. + * function _Node(val, next, random) { * this.val = val; * this.next = next; * this.random = random; @@ -8,30 +8,31 @@ */ /** - * @param {Node} head - * @return {Node} + * @param {_Node} head + * @return {_Node} */ var copyRandomList = function (head) { - if (!head) { + if (head === null) { return null; } - for (let cur = head; cur; ) { - const node = new Node(cur.val, cur.next, null); + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; cur.next = node; cur = node.next; } - for (let cur = head; cur; cur = cur.next.next) { - if (cur.random) { - cur.next.random = cur.random.next; - } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; } + cur = head; const ans = head.next; - for (let cur = head; cur; ) { - const nxt = cur.next; - if (nxt) { - cur.next = nxt.next; - } - cur = nxt; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; } return ans; }; diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.py b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.py index e70ccac9789b0..19d1a1a05693a 100644 --- a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.py +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.py @@ -9,7 +9,7 @@ def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): class Solution: - def copyRandomList(self, head: "Node") -> "Node": + def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]": if head is None: return None cur = head @@ -17,18 +17,14 @@ def copyRandomList(self, head: "Node") -> "Node": node = Node(cur.val, cur.next) cur.next = node cur = node.next - cur = head while cur: - if cur.random: - cur.next.random = cur.random.next + cur.next.random = cur.random.next if cur.random else None cur = cur.next.next - - ans = head.next cur = head - while cur: - nxt = cur.next - if nxt: - cur.next = nxt.next - cur = nxt + ans = head.next + while cur.next: + node = cur.next + cur.next = node.next + cur = node return ans diff --git a/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.ts b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.ts new file mode 100644 index 0000000000000..919200ab30e14 --- /dev/null +++ b/solution/0100-0199/0138.Copy List with Random Pointer/Solution2.ts @@ -0,0 +1,40 @@ +/** + * Definition for _Node. + * class _Node { + * val: number + * next: _Node | null + * random: _Node | null + * + * constructor(val?: number, next?: _Node, random?: _Node) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * this.random = (random===undefined ? null : random) + * } + * } + */ + +function copyRandomList(head: _Node | null): _Node | null { + if (head === null) { + return null; + } + let cur = head; + while (cur !== null) { + const node = new _Node(cur.val); + node.next = cur.next; + cur.next = node; + cur = node.next; + } + cur = head; + while (cur !== null) { + cur.next.random = cur.random === null ? null : cur.random.next; + cur = cur.next.next; + } + cur = head; + const ans = head.next; + while (cur.next !== null) { + const node = cur.next; + cur.next = node.next; + cur = node; + } + return ans; +}