问题:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
分析:直接以一个链表上进行操作。
(1)对原链表的每一个节点进行深复制,并插在源节点的后面。
(2)根据源节点的指针指向对新节点进行引导链接
(3)拆分链表——奇数位为源链表节点,偶数位clone链表节点
code:
/* * 借鉴别人的思想:原链表中,在每个节点后复制一个新节点 * 奇数节点构成老链表序列,偶数节点构成新链表序列 */ public RandomListNode Clone(RandomListNode pHead){ if(pHead==null) { return null; } RandomListNode currentNode = pHead; //复制老节点,并连接在原节点的后面 while(currentNode!=null) { RandomListNode cloneNode = new RandomListNode(currentNode.label); cloneNode.next = currentNode.next; currentNode.next = cloneNode; currentNode = cloneNode.next; } //为新链表设置random指向。 currentNode = pHead; //重置为头结点 while(currentNode!=null) { currentNode.next.random = currentNode.random == null?null:currentNode.random.next; currentNode = currentNode.next.next; } //将当前序列拆分为老链表和新链表 //获得各自的头结点 /* * RandomListNode newHead = pHead.next; RandomListNode newAgent = newHead; * currentNode=pHead; currentNode.next = newAgent.next; currentNode = * currentNode.next; * * //处理后续节点 * while(currentNode!=null) { newAgent.next = currentNode.next; * newAgent = newAgent.next; currentNode = newAgent.next; * * } return newHead; */ currentNode = pHead; RandomListNode pCloneHead = pHead.next; while(currentNode != null) { RandomListNode cloneNode = currentNode.next; currentNode.next = cloneNode.next;
//我在此语句卡住了很久 cloneNode.next = cloneNode.next==null?null:cloneNode.next.next; currentNode = currentNode.next; } return pCloneHead; } public static class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } }