题目
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解决思路
思路1:
先复制原始链表的结点
在元素链表的头结点开始找每个结点的random。每次都要从投开始找,然后连接起来,所以时间复杂度是o(n*n)
思路2:
用空间换时间。创建一个map映射表。<N,N'>(原始结点,复制的结点)。找到结点的random时间复杂度是o(1)。所以最后是o(n)。
思路3:
代码
public class Main {
public static class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null) return null;
//复制原始链表并创建新节点N',把N'连接到N的后面
RandomListNode pNode=pHead;
while(pNode!=null){
RandomListNode pClone=new RandomListNode(pNode.label);
pClone.next=pNode.next;
pClone.random=null;
pNode.next=pClone;
pNode=pClone.next;
}
//设置N'的random
RandomListNode pNode2=pHead;
while(pNode2!=null){
if(pNode2.random!=null){
pNode2.next.random=pNode2.random.next;
}
pNode2=pNode2.next.next;
}
//把长链表拆分成两个链表,奇数位置节点是原始链表,偶数位置的结点是复制后的链表
RandomListNode pNode3=pHead;
RandomListNode pCloneHead=null;
RandomListNode pCloneNode=null;
if(pNode3!=null){
pCloneHead=pCloneNode=pNode3.next;
pNode3.next=pCloneNode.next;
pNode3=pNode3.next;
}
while(pNode3!=null){
pCloneNode.next=pNode3.next;
pCloneNode=pCloneNode.next;
pNode3.next=pCloneNode.next;
pNode3=pNode3.next;
}
return pCloneHead;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
RandomListNode head=new RandomListNode(1);
RandomListNode b=new RandomListNode(2);
RandomListNode c=new RandomListNode(3);
RandomListNode d=new RandomListNode(4);
RandomListNode e=new RandomListNode(5);
head.next=b;
head.random=c;
b.next=c;
b.random=e;
c.next=d;
c.random=null;
d.next=e;
d.random=b;
e.next=null;
e.random=null;
Main m=new Main();
RandomListNode temp=null;
temp=m.Clone(head);
while(temp!=null){
System.out.println(temp.label);
temp=temp.next;
}
}
}