题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
本题思路共分为三个阶段:
阶段一:链表节点的复制
本阶段只需将链表的每个节点复制一次,方法很简单A->B 变为A->A’->B,每次都产生一个新的节点,依次插在原链表每个节点的后面,A‘即为新产生的点。插入操作也是链表的常见操作!
阶段二:还原复制的每个节点的特殊指针指向
因为每个节点有两个指针,第一阶段,我们完成了节点复制,但是其每个节点的特殊指针指向,我们还没有定义,其实复制节点的特殊指针(random指针)指向,为原来本节点的random指针指向节点的下一节点。读者看下面示意图看是否是这么个道理。
阶段三:拆分两个链表
上面两个阶段,我们已经完成的差不多了,接下来需要做的就是分离工作。奇数个节点为本链表,偶数个节点为复制链表,依据这个思想我们可以逐步分离,代码写的比较详细!
图示
阶段一:把复制的结点链接在原始链表的每一对应结点后面
阶段二:把复制的结点的random指针指向被复制结点的random指针的下一个结点
阶段三:拆分成两个链表,奇数位置为原链表,偶数位置为复制链表
代码实现
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
class complexListNode{
int val;
complexListNode next;
complexListNode random;
}
public class copyComplexList {
//复制复杂链表
public void cloneNodes(complexListNode pHead){//第一步:复制节点
complexListNode pNode=pHead;
while (pNode!=null){
complexListNode pClone=new complexListNode();
pClone.val=pNode.val;
pClone.next=pNode.next;
pClone.random=null;
pNode.next=pClone;
pNode=pClone.next;
}
}
public void connectRandomNodes(complexListNode pHead){//第二步:将复制后节点的随机指针连接完成
complexListNode pNode=pHead;
while (pNode!=null){
complexListNode pClone=pNode.next;
if (pNode.random!=null){
pClone.random=pNode.random.next;
}
pNode=pClone.next;
}
}
complexListNode reconnectNodes(complexListNode pHead){//第三步:拆分链表
complexListNode pNode=pHead;
complexListNode pCloneHead=pHead.next;
while (pNode!=null){
complexListNode pClone=pNode.next;
pNode.next=pClone.next;
pClone.next=pClone.next==null?null:pClone.next.next;//此处需要注意,如果循环至链表最后一组节点则会出现next为空,
//所以pclone.next.n错
pNode=pNode.next;
}
return pCloneHead;
}
complexListNode clone(complexListNode pHead){
cloneNodes(pHead);
connectRandomNodes(pHead);
return reconnectNodes(pHead);
}
public static void main(String[] args) {
complexListNode node1=new complexListNode();
complexListNode node2=new complexListNode();
complexListNode node3=new complexListNode();
complexListNode node4=new complexListNode();
complexListNode node5=new complexListNode();
node1.val=11; node1.next=node2; node1.random=node4;
node2.val=21; node2.next=node3; node2.random=node5;
node3.val=31; node3.next=node4; node3.random=node1;
node4.val=41; node4.next=node5; node4.random=node2;
node5.val=51; node5.next=null; node5.random=node3;
copyComplexList test=new copyComplexList();
complexListNode node = test.clone(node1);
System.out.println(node.val+" "+node.random.val+" "+node.next.next.val);
}
}
总结
本题来源于面试经典教材《剑指offer》中 归属于链表类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
最后,感谢Jerry算法!
明天开始比赛,这周先断更几天,下周多更新几次!!!!!!!!!
加油 冲冲冲!!!!!!