1.题目
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
2.我的题解
步骤:
- 先在原链表中的每两个节点中间添加一个节点,该节点的
label
等于前一个节点。这样相当于将原来的label、next
复制了一份。我们用主副链表称呼。 - 再为新添加的节点添加
random
指针,使得副链表和主链表的random
指针具有相同的规律。 - 拆分主副链表,只需要改变
next
指针即可。
注意:
- 节点可能为空。
- 后两步只需要进行到总(主副)链表的倒数第二个节点。
random
指针可能指向NULL
,需要判断。
举个例子(简单起见,random
指向自己)。
步骤 | 图示 |
---|---|
原链表 | |
添加节点 | |
复制random | |
拆分 |
用的不熟练,巨丑……还是手画流程图吧。
步骤 | 图示 |
---|---|
原链表 | ![]() |
添加节点 | ![]() |
复制random | ![]() |
拆分 | ![]() |
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
if(!pHead)return NULL;
RandomListNode * cur = pHead;
//copy (next)
while(cur){
RandomListNode * tmp =new RandomListNode(cur->label);
tmp->next=cur->next;
cur->next=tmp;
cur=tmp->next;
}
//copy (random)
cur=pHead;
while(cur && cur->next){
if(cur->random)//随机指向的节点可能为空
cur->next->random=cur->random->next;
cur=cur->next->next;
}
//seperate
cur=pHead;
RandomListNode * res = pHead->next;
while(cur && cur->next){
RandomListNode * tmp =cur->next;
cur->next=tmp->next;
cur=tmp;
}
return res;
}
};
3.别人的题解
4.总结与反思
(1)http://g.gravizo.com有意思的画图网站。第一次用,画的巨难看,使的不熟练。
(2)https://www.processon.com在线画流程图,挺好用的。