剑指Offer29--面试题35.复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
代码
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
copy(pHead);
addRandom(pHead);
return build(pHead);
}
// 将复制的节点放在原节点后面
void copy(RandomListNode pHead){
RandomListNode node = pHead;
while(node!=null){
// 建原节点
RandomListNode cloned = new RandomListNode(node.label);
// 复制节点
//cloned.label = node.label;
cloned.random = null;
// 插入节点
cloned.next = node.next;
node.next = cloned;
node = cloned.next;
}
}
// 复制对应的random
void addRandom(RandomListNode pHead){
RandomListNode node = pHead;
while(node!=null){
// 找到复制节点
RandomListNode cloned = node.next;
if(node.random!=null){
// 将原节点的随机指向节点 复制给 复制节点
cloned.random = node.random.next;
}
node = cloned.next;
}
}
// 将所有的原节点都删除
RandomListNode build(RandomListNode pHead){
//将链表拆成两个,注意要恢复原有的链表
RandomListNode node = pHead;
// 复制链表
RandomListNode cloneHead = null;
RandomListNode cloneNode = null;
if(node!=null){
// 取到复制节点的第一个节点
cloneHead = cloneNode = node.next;
// 将节点
node.next = cloneNode.next;
node = node.next;
}
while(node!=null){
// 形成复制链表
cloneNode.next = node.next;
cloneNode = cloneNode.next;
// 形成原始链表
// 这一步不可缺少,保证第一个复制节点对N N'的分离操作
node.next = cloneNode.next;
node =node.next;
}
return cloneHead;
}
}