【剑指offer】【链表】35. 复杂链表的复制
题目链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
哈希
用哈希表做一个映射,hashmap的key是原先的节点,val是复制的节点。先初始化hashmap,然后分别next指针和random指针。
哈希表的作用:找到每个点的对应点(复制点)
时间复杂度O(n) 空间复杂度O(n)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(!head) return head;
//使用哈希来做一个映射
unordered_map<Node*, Node*> pos;
pos[NULL] = NULL;
//先复制正常的next节点,不复制random节点
for(auto p = head; p; p = p -> next)
pos[p] = new Node(p -> val);
//复制指针的指向
for(auto p = head; p; p = p -> next)
{
pos[p] -> next = pos[p -> next];
pos[p] -> random = pos[p -> random];
}
return pos[head];
}
};
迭代
先复制正常的next节点,不复制random节点。之后复制指针的指向
时间复杂度O(n) 空间复杂度O(1)
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
//在每个节点后面添加它的复制
//复制next节点 复制的节点保存在原先节点的next指针处
//新复制的节点的next指针的原先节点的next指针
//原先: 1->2->3->4->5->null
//now: 1->1->2->2->3->3->4->4->5->5->null
for(auto p = head; p;)
{
auto np = new Node(p -> val);
auto next = p -> next;
p -> next = np;
np -> next = next;
p = next;
}
//复制random指针
for(auto p = head; p; p = p -> next -> next)
if(p -> random)
p -> next -> random = p -> random -> next;
//原链表不能修改 还原
//遍历链表 分开两个链表
auto dummy = new Node(-1);
auto cur = dummy;
for(auto p = head; p; p = p -> next)
{
cur -> next = p -> next;
cur = cur -> next;
p -> next = p -> next -> next;
}
return dummy -> next;
}
};
知识的价值不在于占有,而在于使用

浙公网安备 33010602011771号