输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
(图片来自cyc2018)
public class Solution { public RandomListNode Clone(RandomListNode pHead) { if(pHead == null) return null; RandomListNode cur = pHead; // 复制节点 while(cur != null){ RandomListNode clone = new RandomListNode(cur.label); clone.next = cur.next; cur.next = clone; cur = clone.next; // 因为cur、pHead都是引用,指向同一个链表,到这步节点已经复制并保存在pHead指向的链表中, } // 所以cur = clone.next 不会覆盖已经复制的链表,只是cur指向了别的地方,如果还不理解,去看java内存分析 // 设置随机指针 cur = pHead; while(cur != null){ cur.next.random = (cur.random != null)?cur.random.next:null; //这里要判断cur.random是否为空,否则会报空指针异常 cur = cur.next.next; } // 分离 cur = pHead; RandomListNode dupHead = cur.next; while(cur.next!= null){ RandomListNode next = cur.next; cur.next = next.next; cur = next; } return dupHead; } }
另外,关于分离的部分,第一次写的代码是:
// 分离 cur = pHead; RandomListNode dupHead = cur.next; while(cur.next.next!= null){ cur.next = cur.next.next; cur = cur.next; }
不用cur.next过度,直接用cur.next.next,会在原链表只有一个节点的时候报空指针异常。
原文:https://www.cnblogs.com/tendermelon/p/13061579.html