劍指 Offer 35. 複雜鏈錶的複製
劍指 Offer 35. 複雜鏈錶的複製
Question
請實現 copyRandomList 函數,複製一個複雜鏈錶。在複雜鏈錶中,每個節點除了有一個 next 指針指向下一個節點,還有一個 random 指針指向鏈錶中的任意節點或者 null。
Example 1:
Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
Example 2:
Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]
Example 3:
Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]
Example 4:
Input: head = []
Output: []
相關說明
本題難點為再複製鏈表的過程建立各節點的 Random 指向。普通鏈表的深拷貝可以按順序創建表節點,但因 Random 指向的節點可能尚未建立,因此需要變換思路。
思路1
解題詳解:
使用拼接與拆分的方式,
1. 先在原節點後複製新節點構建拼接鏈表,
將 old1 → old2 → old3 調整為 old1 → new1 → old2 → new2 → old3 → new3
new1 使用 old1 的 val 建立 node,
old1 的 next 指到 new1 ,new1 的 next 指到 old2。
2. 指定 new 的 Random 為 old 的 Random 的 next
例如 old1.random 為 old3,old1.random.next 就會是 new3,再賦值回 new1.random
3. 拼接完鏈表的 new Next Random 後,接著要拆分鏈表並只返回 new 的部分,
設 res 紀錄 new 的頭節點,將 new 拆分後返回 res。
Big-O
時間複雜度 O(n)
空間複雜度 O(1)
代碼
語言: python3
執行用時: 36ms
內存消耗: 15.9 MB
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head: return None
cur = head
while cur != None:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
cur = head
while cur != None:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
pre = head
cur = head.next
res = cur # 最後要返回頭節點
while cur.next != None:
pre.next = pre.next.next
cur.next = cur.next.next
pre = pre.next
cur = cur.next
pre.next = None # 處理原鏈表結尾
return res
語言: golang
執行用時: 0ms
內存消耗: 3.4 MB
/**
* Definition for a Node.
* type Node struct {
* Val int
* Next *Node
* Random *Node
* }
*/
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
for cur := head; cur != nil; cur = cur.Next.Next {
cur.Next = &Node{Val: cur.Val, Next: cur.Next}
}
for cur := head; cur != nil; cur = cur.Next.Next {
if cur.Random != nil {
cur.Next.Random = cur.Random.Next
}
}
res := head.Next
for cur := head; cur != nil; cur = cur.Next {
curNew := cur.Next
cur.Next = cur.Next.Next
if curNew.Next != nil {
curNew.Next = curNew.Next.Next
}
}
return res