题目描述
请实现函数,用于复制一个复杂链表。在复杂链表中,每个结点除了有一个next指针指向下一个结点外,还有一个sibling指向链表中的任意结点或者NULL。
复杂链表如下图:
复杂节点定义如下:
public class ComplexListNode {
int value;
ComplexListNode next;
public ComplexListNode() {
}
ComplexListNode sibling;
public ComplexListNode(int value) {
this.value = value;
}
}
解题思路
- 在每个节点的后面插入复制的节点,如下图:
- 对复制的节点的sibling指针进行赋值,如下图:
将上面的链表拆成两个链表,原始链表和复制链表,如下图:
代码
public class Clone {
public static ComplexListNode clone(ComplexListNode head) {
cloneNodes(head);
connectSiblingNodes(head);
return reconnectNodes(head);
}
// 复制链表节点,把复制后的节点N'放在原节点N的后面
public static void cloneNodes(ComplexListNode head) {
while (head != null) {
ComplexListNode cloned = new ComplexListNode();
cloned.value = head.value;
cloned.next = head.next;
cloned.sibling = null;
head.next = cloned;
head = cloned.next;
}
}
// 设置复制出来的节点的sibling
public static void connectSiblingNodes(ComplexListNode head) {
while (head != null) {
ComplexListNode cloned = head.next;
cloned.sibling = head.sibling.next;
head = cloned.next;
}
}
// 把这个长链表拆分为两个链表
public static ComplexListNode reconnectNodes(ComplexListNode head) {
// 复制链表的头结点
ComplexListNode clonedHead = null;
// 用于临时存储复制链表的节点
ComplexListNode clonedNode = null;
if (head != null) {
// 设置复制链表的头结点
clonedHead = clonedNode = head.next;
head.next = clonedHead.next;
head = head.next;
}
while (head != null) {
clonedNode.next = head.next;
clonedNode = clonedNode.next;
head.next = clonedNode.next;
head = head.next;
}
return clonedHead;
}
// 打印,用于测试
public static void printNodes(ComplexListNode head) {
System.out.println("head.value" + "\t" + "head.sibling.value");
while (head != null) {
System.out.print(head.value + "\t" + "\t" + "\t");
if (head.random != null) {
System.out.print(head.random.value);
} else {
System.out.print("null");
}
System.out.println();
head = head.next;
}
}
// 测试程序
public static void main(String[] args) {
ComplexListNode node1 = new ComplexListNode(1);
ComplexListNode node2 = new ComplexListNode(2);
ComplexListNode node3 = new ComplexListNode(3);
node1.next = node2;
node2.next = node3;
node1.sibling = node3;
node2.sibling = node1;
node3.sibling = node2;
// 复制后的链表
ComplexListNode cloned = clone(node1);
printNodes(cloned);
System.out.println();
// 不影响原链表
printNodes(node1);
}
}
来自:
《剑指Offer》
Coding-Interviews/复杂链表的复制.md at master · todorex/Coding-Interviews