版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24634505/article/details/81047955
题目描述
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
- 无测试用例
思路
首先注意这道题要求返回一个深拷贝的链表,因此要依次复制每个节点。但难点在于有一个指向链表中随机节点,这需要我们了解链表随机两个节点间的链接关系。
方法1 用map结构保存拷贝节点与原节点的一一对应关系
第一遍,依次复制每个节点,用map保存拷贝的节点与原节点的对应关系。对于当前复制的节点,检查其next节点是否在map中出现,如果有,说明原链表中出现了环,拷贝节点的next需要指向原节点的对应的节点,如果没有则新建节点插入链表,并保存对应关系。
第二遍,如果原节点的random节点不为空,就依次检查原节点的random节点是否在map中出现,如果有,找出该节点在拷贝链表中对应的节点。
这种方法需要两次遍历链表,还需额外开辟空间保存两个链表的对应关系,复杂度比较高。
class Solution {
public:
map<RandomListNode*,RandomListNode*> data;//head,chead
RandomListNode* CheckForDup(RandomListNode* p)
{
for(auto i=data.begin();i!=data.end();i++)
{
if(i->first==p)
{
return i->second;
}
}
return NULL;
}
RandomListNode *copyRandomList(RandomListNode *head) {
if(head==NULL)return NULL;
RandomListNode* chead=new RandomListNode(head->label);
RandomListNode* q=chead;
RandomListNode* p=head;
data.insert(pair<RandomListNode*,RandomListNode*>(head,chead));
while(p->next)
{
RandomListNode* tmp = CheckForDup(p->next);
if(tmp)
q->next=tmp;
else{
q->next=new RandomListNode(p->next->label);
data.insert(pair<RandomListNode*,RandomListNode*>(p->next,q->next));
}
q=q->next;
p=p->next;
}
q=chead;
p=head;
while(p)
{
if(p->random==NULL)
{
q->random=NULL;
}
else{
q->random=CheckForDup(p->random);
}
p=p->next;
q=q->next;
}
return chead;
}
};
方法2 利用原节点顺序找对应关系
刚刚的做法是连对应关系也重新新建了一份,过分囿于单个节点与next、random之间的对应关系。其实节点间的对应关系就保存在原链表里,利用节点的排列顺序就可以得到。将所有拷贝节点创建在原节点的next的位置就可以快速的找到random节点的对应关系了。
最后遍历链表将交错的两个链表拆开。
我失骄阳君失柳,杨柳轻扬直上重霄九。问讯吴刚何所有,吴刚捧出桂花酒。
寂寞嫦娥舒广袖,万里长空且为忠魂舞。忽报人间曾伏虎,泪飞顿作倾盆雨。