描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。
示例:
输入:{1,2,3,4,5,3,5,#,2,#}
输出:{1,2,3,4,5,3,5,#,2,#}
解析:我们将链表分为两段,前半部分{1,2,3,4,5}为ListNode,后半部分{3,5,#,2,#}是随机指针域表示。
以上示例前半部分可以表示链表为的ListNode:1->2->3->4->5
后半部分,3,5,#,2,#分别的表示为
1的位置指向3,2的位置指向5,3的位置指向null,4的位置指向2,5的位置指向null
如下图:
示例1
输入:
{1,2,3,4,5,3,5,#,2,#}
复制返回值:
{1,2,3,4,5,3,5,#,2,#}
标准做法:就地复制(则复制了所有指向信息),双指针遍历倍长链表,啥都有了
千万注意,原链表一点不能变,一定要完整还原,否则判错
public RandomListNode Clone2(RandomListNode pHead) {
if(pHead==null) return null;
RandomListNode p1=pHead,p2=pHead;
//就近复制
while (p1!=null){
RandomListNode temp = new RandomListNode(p1.label);
RandomListNode t=p1.next;
p1.next=temp;
temp.next=t;
p1=t;
}
p1=p2.next;
while (p1.next!=null){//p2原链找random p1拷贝链表
if(p2.random==null) p1.random=null;
else p1.random=p2.random.next;
p1=p1.next.next;
p2=p2.next.next;
}//暂时不能拆链表 一步步来
p1=pHead.next;p2=pHead;
RandomListNode ans=p1;
while (p1.next!=null){
p2.next=p2.next.next;
p2=p2.next;//注意p2也要处理 原链表不能被破坏 否则判错
p1.next=p1.next.next;//拷贝链p1在后,后处理 否则影响p2的拆下
p1=p1.next;
}
p2.next=null;//原链表一点不能变
return ans;
}
脑子笨,做过的题都会,没做过的只会暴力
我得做法:最蠢暴力
public RandomListNode Clone(RandomListNode pHead) {
RandomListNode ans=new RandomListNode(-1);
RandomListNode ansHead = ans;
RandomListNode p = pHead;
//先克隆节点
while (p!=null){
RandomListNode temp = new RandomListNode(p.label);
ans.next=temp;
ans=ans.next;
p=p.next;
}
//pHead.show();
//再克隆随机指针
ans=ansHead.next;
p=pHead;
while (p!=null){
if(p.random==null) ans.random=null;//小心
else ans.random=getNode(ansHead.next,getIndex(pHead,p.random));//千万注意每次从ansHead.next开头找
p=p.next;
ans=ans.next;
}
return ansHead.next;
}
public RandomListNode getNode(RandomListNode pHead,int k){
while (--k!=0){
if(pHead==null) return null;
pHead=pHead.next;
}
return pHead;
}
public Integer getIndex(RandomListNode pHead,RandomListNode randomNode){
if(randomNode==null) return null;
int k=0;
while (pHead!=null){
k++;
if(pHead==randomNode) break;
pHead=pHead.next;
}
return k;
}