【在线编程】复杂链表的复制
【问题描述】
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
【解题思路 & Java实现】
方法一:依次复制每个结点以及该结点的next结点和random结点。时间复杂度O(n),空间复杂度O(3n)。这会造成空间浪费。
/*
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) {
if (pHead == null) {
return null;
}
RandomListNode newHead = new RandomListNode(-1); //辅助头结点
RandomListNode p = newHead; //新链表的工作结点
while (pHead != null) {
//复制当前结点
RandomListNode copy = new RandomListNode(pHead.label);
//复制当前结点的next结点
RandomListNode copyNext = null;
if (pHead.next != null) {
copyNext = new RandomListNode(pHead.next.label);
}
//复制当前结点的random结点
RandomListNode copyRandom = null;
if (pHead.random != null) {
copyRandom = new RandomListNode(pHead.random.label);
}
copy.next = copyNext;
copy.random = copyRandom;
p.next = copy;
p = p.next;
pHead = pHead.next;
}
return newHead.next;
}
}
方法二:首先分别复制每个结点,挂在对应结点的后面;然后设置复制结点的 random 域;最后进行断链,将原链表和复制链表分开。
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public static RandomListNode Clone(RandomListNode pHead) {
if (pHead == null) {
return null;
}
//1. 复制结点,并将复制的结点挂在对应结点后面
RandomListNode p = pHead;
while (p != null) {
RandomListNode copy = new RandomListNode(p.label);
copy.next = p.next;
p.next = copy;
p = copy.next;
}
//2. 设置复制结点的 random 指针
p = pHead;
while (p != null) {
if (p.random != null) {
p.next.random = p.random.next;
}
p = p.next.next;
}
//3. 断链,断开原链表和复制的链表
p = pHead;
//复制链表的头结点
RandomListNode newHead = pHead.next;
//复制链表的工作指针
RandomListNode newP = newHead;
while (p != null) {
p.next = newP.next;
if (newP.next != null) {
newP.next = newP.next.next;
}
p = p.next;
newP = newP.next;
}
return newHead;
}
}
注意点:
(1)一定要注意结点的索引和结点的复制是不同的,结点的复制是需要 new 的。
(2)一定要注意 NullPointerException: 一切对 null 对象的操作都会出现 NullPointerException。