2021/4/3,依旧是剑指Offer的一天,题意如下:
第一个思路肯定是先跑一边把所有链表都记下来,然后再创建一个链表从头连起来就好了。当然这样的空间复杂度会到O(N),然后看到题解的思路顿时觉得牛哇。思路是在每个节点后再复制一个节点,然后根据原节点的random的值去让复制的这个节点去指向复制的random的值,最后再把这两个链表拆开就好了,具体做法看代码吧,膜拜大佬中orz
第一种思路:
/*
// 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==nullptr)
return nullptr;
map<Node*,Node*> mp;
Node *now=head;
while(now!=nullptr)
{
mp[now]=new Node(now->val);
now=now->next;
}
now=head;
while(now!=nullptr)
{
mp[now]->next=mp[now->next];
mp[now]->random=mp[now->random];
now=now->next;
}
return mp[head];
}
};
时间复杂度O(N),空间复杂度O(N)。
第二种:
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==nullptr)
return nullptr;
Node *now=head;
while(now!=nullptr)//复制链表(拼接)
{
Node *t=new Node(now->val);
t->next=now->next;
now->next=t;
now=now->next->next;
}
now=head;
Node *ans=head->next;
while(now!=nullptr)//让复制的链表random指向原链表的random
{
if(now->random!=nullptr)
{
now->next->random=now->random->next;//因为紧跟在后面所以next就是
}
now=now->next->next;
}
Node *now2=ans;
now=head;
while(now2->next!=nullptr)//恢复两个链表(拆分)
{
now->next=now->next->next;
now2->next=now2->next->next;
now=now->next;
now2=now2->next;
}
now->next=nullptr;//最后要复原原链表
return ans;
}
};
时间复杂度O(N),空间复杂度O(1)。
参考资料
·依旧是被K神折服的一天