剑指offer : 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点), 返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
思路:
分三步:
* 1)将原来的链表的每一个节点(老节点)复制出一个新的节点,并将该新节点插入到对应的老节点后面即老节点的next指向新复制的节点)
* 即: A->B->C 变成 A->A'->B->B'->C->C'
* 2)利用老节点的next指向的是该老节点复制出来的新节点,老节点的random指向的是老节点的随机节点,那么该随机节点的next就是该随机节点的复制的新节点(所以新节点的random指向老节点的random的next)
* newNode=oldNode.next; newNode.random=oldNode.random.next;
* 3)将原来的链表拆分成两个链表,奇数位上的连起来是原来的链表,偶数位上的连起来是复制的链表
public class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } } public class Solution{ /** * @param pHead * @return */ public RandomListNode Clone(RandomListNode pHead) { RandomListNode oldNode=pHead; if(pHead==null){ return null; } //第一步,复制每个节点并插入到老节点后面 while(oldNode!=null){ RandomListNode newNode=new RandomListNode(oldNode.label); //生成一个新节点,其label和老节点一样 newNode.next=oldNode.next; //将newNode插入老节点和他的next节点之间 oldNode.next=newNode; oldNode=oldNode.next.next; //指向下一个老节点 } //第二步,将新节点的随机节点设好 oldNode=pHead; while(oldNode!=null){ RandomListNode newNode=oldNode.next; //oldnode的next节点就是复制的老节点 if(oldNode.random!=null){ newNode.random=oldNode.random.next; //oldNode的random指向的是老节点的随机节点,而该随机节点的next便是该随机节点的复制节点(也就是该老节点的复制的新节点的random指向的随机节点) } oldNode=newNode.next; } //第三步,将原来的链表进行拆分 oldNode=pHead; RandomListNode copyHead=oldNode.next; while(oldNode!=null){ RandomListNode copyNode=oldNode.next; //指向复制出来的第一个节点 oldNode.next=copyNode.next; //指向oldNode的原来的next节点 if(copyNode.next!=null){ copyNode.next=copyNode.next.next; //更新copyNode的next } oldNode=oldNode.next; //因为已经更新过了oldNode的next } return copyHead; } }