題目描述:
輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果為復制后復雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)。
解題思路:
本題有以下三種解法:
第一種:先按照next復制,然后依次添加random指針,添加時需要定位random的位置,定位一次需要一次遍歷,需要O(n^2)的復雜度。
第二種:先按照next復制,然后用一個hashmap保存原節點和復制后節點的對應關系,則用O(n)的空間復雜度使時間復雜度降到了O(n)。
第三種(最優方法):同樣先按next復制,但是把復制后的節點放到原節點后面,則可以很容易的添加random,最后按照奇偶位置拆成兩個鏈表,時間復雜度O(n),不需要額外空間。
舉例:
編程實現(Java):
public class Solution {
public RandomListNode Clone(RandomListNode pHead){
if(pHead==null)
return null;
//(1)先按next復制,但是把復制后的節點放到對應原節點后面
CopyNodes(pHead);
//(2)依次添加random指針
addRandom(pHead);
//(3)按照奇偶位置拆成兩個鏈表
return ReconnectNodes(pHead);
}
//先按next復制,但是把復制后的節點放到對應原節點后面
public void CopyNodes(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode temp=new RandomListNode(head.label);
temp.next=head.next; //復制一個結點,插在對應的原節點的后面
temp.random=null;
head.next=temp;
head=temp.next;
}
}
//依次添加random指針
public void addRandom(RandomListNode pHead){
RandomListNode head=pHead;
while(head!=null){
RandomListNode head_new=head.next;
if(head.random!=null)
head_new.random=head.random.next;
head=head_new.next;
}
}
//按照奇偶位置拆成兩個鏈表
public RandomListNode ReconnectNodes(RandomListNode pHead){
if(pHead==null)
return null;
RandomListNode head=pHead;
RandomListNode pHeadClone=head.next;
RandomListNode headClone=pHeadClone;
while(head!=null){
head.next=headClone.next;
head=head.next;
if(head!=null){
headClone.next=head.next;
headClone=headClone.next;
}
}
return pHeadClone;
}
}
