题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
1.最开始的时候,一下子就想到了递归,跑了一下通过了。
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null)
return null;
//开辟一个新节点
RandomListNode newHead=new RandomListNode(pHead.label);
newHead.random = pHead.random;
//递归其他节点
newHead.next=Clone(pHead.next);
return newHead;
}
}
在这个题目中,节点的开辟空间以及next指针的遍历是简单的,难点在于如何将random引用指向新开辟的节点。
所以采用下面的方法。
2.
第一步,遍历开辟复制的新节点,为了让接下来的random指针可以准确定位,在这里采用了将复制节点插入到原链表中。
比如原来是A->B->C 变成A->A'->B->B'->C->C'
第二步,遍历设置random引用指向的节点,由于新节点都在原节点的后面,所以只需要指向原random.next即可。
第三部,将新链表拆出来。
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null) return null;
//遍历插入新的节点
RandomListNode Cur1 = pHead;
while(Cur1!=null){
RandomListNode newNode = new RandomListNode(Cur1.label);
newNode.next=Cur1.next;
Cur1.next=newNode;
Cur1=newNode.next;
}
//设置random引用
Cur1=pHead;
while(Cur1!=null){
if(Cur1.random!=null)
Cur1.next.random=Cur1.random.next;
Cur1=Cur1.next.next;
}
//拆分链表
RandomListNode head = pHead.next;
RandomListNode Cur2 = head;
Cur1 = pHead;
while(Cur1!=null){
Cur1.next = Cur1.next.next;
if(Cur2.next!=null)
Cur2.next = Cur2.next.next;
Cur2 = Cur2.next;
Cur1 = Cur1.next;
}
return head;
}