哈希表:
第一次遍历原链表(已用 next 指针连接,用 while(cur != nullptr)循环 cur = cur->next 遍历),复制遍历过的节点(创建新节点)。
c++
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head == nullptr){
return nullptr;
}
// 复制节点 值
Node* cur = head; // 创建新指针(用于复制链表), 指向头指针
unordered_map<Node*, Node*> mp; // 哈希表<键,对> <旧节点, 复制后新节点(节点值)>
while(cur != nullptr){
mp[cur] = new Node(cur->val); // 复制(创建新节点Node,放入原节点值)
cur = cur->next; // 继续复制下一个节点 <指针, 值>
}
cur = head;
// 复制节点 next 和 random
while(cur != nullptr){ // mp[cur] 即刚刚创建的 new Node
mp[cur]->next = mp[cur->next]; // ->next 连接下一个节点 mp[cur->next]
mp[cur]->random = mp[cur->random];
cur = cur->next;
}
return mp[head]; // 返回新链表的头节点
}
};
python
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return None
dic = {}
cur = head
while cur:
dic[cur] = Node(cur.val)
cur = cur.next
cur = head
while cur: # dic[cur] = Node(cur.val)
dic[cur].next = dic.get(cur.next) # 如果用 = dic[cur.next], 如果cur.next = null则keyerror
dic[cur].random = dic.get(cur.random)
cur = cur.next
return dic[head]
拼接+拆分:
c++ 创建新节点 Node* tmp = new Node(cur->val);
python 创建新节点 tmp = Node(cur.val)
c++
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head == nullptr){
return nullptr;
}
// 插入(复制)
Node* cur = head;
while(cur != nullptr){
Node* tmp = new Node(cur->val); // 创建新节点new Node,节点放入数据值
tmp->next = cur->next;
cur->next = tmp;
cur = tmp->next; // 复制下一个节点
}
// 新节点添加random指针
cur = head;
while(cur != nullptr){
if(cur->random != nullptr){ // 只遍历旧节点
// cur->next->random 新插入节点, cur->random->next 原节点的random节点的复制节点
cur->next->random = cur->random->next;
}
cur = cur->next->next; // cur->next是复制的节点, cur->next->next是原节点的下个节点
}
// 拆分两链表
cur = head->next; // cur从复制节点开始
Node* pre = head; // pre从头节点开始
Node* res = head->next; // res原始第一个复制节点
while(cur->next != nullptr){ // 复制后链表最后一个是复制节点
pre->next = pre->next->next; // pre一直指向原链表节点
cur->next = cur->next->next; // cur一直指向复制节点
pre = pre->next;
cur = cur->next;
}
pre->next = nullptr; // 单独处理原链表尾节点
return res; // 返回新链表头节点
}
};
python
"""
# 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:
tmp = Node(cur.val) # 创建新节点,并加入节点值
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
# 构建各新节点的 random 指向
cur = head
while cur:
if cur.random: # 只处理链表原节点
cur.next.random = cur.random.next
cur = cur.next.next
# 拆分两链表
pre = head
res = cur = head.next
while cur.next: # 链表尾结点是复制节点
pre.next = pre.next.next # pre只遍历原链表节点
cur.next = cur.next.next # cur只遍历原链表复制节点
pre = pre.next
cur = cur.next
pre.next = None # 单独处理原链表尾结点
return res