题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的头结点。
思路:
1. 首先根据链表的next遍历一遍,在每个node节点的后面复制一个与node的label相等的节点,如图所示;
2. 再遍历新链表,为复制的节点指定random指针(黄色箭头所示);
3. 将新链表拆分=原链表+复制后的链表
4. 在操作过程中一定要主要判断节点是否为空
5. 时间复杂度o(n),空间复杂度o(n)
示例代码如下:
/**
* Copyright (C), 2017
* FileName: Main
* Author: Mengjun Li
* Date: 2017/10/3 上午11:09
* Description:
*/
/**
* @author Mengjun Li
* @create 2017/10/3
* @since 1.0.0
*/
public class Main {
public static void main(String args[]) {
//定义测试节点
RandomListNode node1 = new RandomListNode(1);
RandomListNode node2 = new RandomListNode(2);
RandomListNode node3 = new RandomListNode(3);
RandomListNode node4 = new RandomListNode(4);
RandomListNode node5 = new RandomListNode(5);
RandomListNode node6 = new RandomListNode(6);
node1.next = node2;
node1.random = node3;
node2.next = node3;
node2.random = node4;
node3.next = node4;
node3.random = node1;
node4.next = node5;
node4.random = node2;
node5.next = node6;
node5.random = null;
node6.random = node5;
System.out.println("原链表的next指针");
while (head != null) {
System.out.print(head.label + "-->");
head = head.next;
}
System.out.println("null");
//Clone链表
head = Clone(node1);
System.out.println("clone的链表的next指针");
while (head != null) {
System.out.print(head.label + "-->");
head = head.next;
}
System.out.println("null");
System.out.println("原链表的random指针");
head = node1;
while (head != null) {
if (head.random != null)
System.out.print(head.label + "-->"+head.random.label+", ");
else
System.out.print(head.label + "--> null, ");
head = head.next;
}
System.out.println("");
head = Clone(node1);
System.out.println("clone的链表的random指针");
while (head != null) {
if (head.random != null)
System.out.print(head.label + "-->"+head.random.label+", ");
else
System.out.print(head.label + "--> null, ");
head = head.next;
}
}
public static RandomListNode Clone(RandomListNode pHead) {
if (pHead == null)
return pHead;
RandomListNode tmp = null, oHead = pHead, newNode;
//第一步:在原链表中每一个节点的后面复制前面一个节点
while (oHead != null) {
newNode = new RandomListNode(oHead.label);
tmp = oHead.next;
oHead.next = newNode;
newNode.next = tmp;
oHead = tmp;
}
oHead = pHead;
//第二步:给复制的节点的random指针赋值
while (oHead != null) {
if (oHead.random != null)//random可能为null
oHead.next.random = oHead.random.next;
else
oHead.next.random = null;
oHead = oHead.next.next;
}
//将复制后的链表和原链表断开
oHead = pHead;
newNode = pHead.next;
while (oHead != null) {
tmp = oHead.next;
if (tmp != null)
oHead.next = tmp.next;
oHead = tmp;
}
return newNode;
}
}
class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
输出如下:
原链表的next指针
1-->2-->3-->4-->5-->6-->null
clone的链表的next指针
1-->2-->3-->4-->5-->6-->null
原链表的random指针
1-->3, 2-->4, 3-->1, 4-->2, 5--> null, 6-->5,
clone的链表的random指针
1-->3, 2-->4, 3-->1, 4-->2, 5--> null, 6-->5,