题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
分析:分为三步骤:
1)复制每个节点,如复制A得到A1,并将A1插入到A的后面
2)重新遍历链表,复制老节点的指针给新节点
3)拆分链表,将链表拆分为原链表和复制后的链表
代码实现:
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if (pHead == null) {
return null;
}
RandomListNode currentNode = pHead;
// 1、复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面;
while(currentNode!=null){
int temp = currentNode.label;
RandomListNode p = new RandomListNode(temp); //复制每个节点
p.next = currentNode.next; //将复制的节点逐个插入链表
currentNode.next = p;
currentNode = currentNode.next.next; //注意currentNode.next肯定不为空
}
currentNode = pHead;
// 2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next;
while(currentNode!=null){
RandomListNode p = currentNode.next;
if(currentNode.random!=null)
p.random = currentNode.random.next;
currentNode = currentNode.next.next;
}
// 3、拆分链表,将链表拆分为原链表和复制后的链表
RandomListNode pCur;
RandomListNode Cur;
RandomListNode head;
pCur = pHead;
Cur = head = pHead.next;
while(pCur!=null){
pCur.next = pCur.next.next; //执行这段语句时,确认pCur不为null,因为两个一对
if(Cur.next!=null){
Cur.next = Cur.next.next; //Cur.next是不是null就不一定了
}
pCur = pCur.next;
Cur = Cur.next;
}
return head;
}
}
说明:while(pCur!=null){
pCur.next = pCur.next.next; //执行这段语句时,确认pCur不为null,因为两个一对
if(Cur.next!=null){
Cur.next = Cur.next.next; //Cur.next是不是null就不一定了
}
pCur = pCur.next;
Cur = Cur.next;
}
对这几行代码的说明:1)复制random指针时:
复制的节点的random指针的值是被复制节点的random指针指向节点的下一个节点。
p.random = currentNode.random.next;
2)拆分节点时:pCur.next = pCur.next.next,这里不用考虑pCur.next是不是为null,因为复制完后是成对出现的,所以pCur后面的一定不为null,但是Cur.next就不一定了,所以要加上判读if(Cur.next!=null)来进行判别。
参考:牛客网通过代码https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba