Java單鏈表(帶random指針)深拷貝(Copy List with Random Pointer)


問題:

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

 

結點的定義如下:

/** 
* Definition for singly-linked list with a random pointer. 
* class RandomListNode { 
*     int label; 
*     RandomListNode next, random; 
*     RandomListNode(int x) { this.label = x; } 
* }; 
*/

分析:

原來的鏈表的結構如下圖所示:

image

注意一點,random的指針可以指向后面的結點,也可以指向前面的結點。

 

這里提供兩種解法:

 

方法1:用hash表存儲結點信息,時間O(2n),空間O(n)

第一次遍歷原鏈表,並構建random為null的新鏈表,於此同時在hash表中存儲原結點和新結點的地址信息,原結點地址為key,新結點地址為value,即map<原結點地址,新結點地址>

第二次遍歷原鏈表,對於random不為空的結點,可以根據random的值,在hash表中找到random指向的節點對應的新結點的地址,再以此給新結點random賦值即可。

 

方法2:先改變原鏈表的結構,在恢復,時間O(2n),空間O(1)

這個方法需要3次遍歷,

第一次,構建新鏈表的結點,random為null,並且用原來鏈表節點的next指向對應的新結點,新結點的next指向原鏈表的下一個結點,如圖所示:

 

image

第二次,給新節點的random賦值,

復制代碼
p = head;
        while(p!=null){
            if(p.random != null){
                p.next.random = p.random.next;
            }
            p = p.next.next;
        }
復制代碼

第三次,恢復原鏈表和新鏈表的鏈表結構。

復制代碼
head2 = head.next;
        p = head;
        while(p!=null){
            p2 = p.next;
            p.next = p2.next;
            if (p2.next != null) p2.next = p2.next.next;
            p = p.next; 
        }
復制代碼

 方法2的完整代碼:

復制代碼
public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        if(head == null)return null;
        RandomListNode head2,p2,p = head;
        while(p!=null){
            RandomListNode n = new RandomListNode(p.label);
            n.next = p.next;
            p.next = n;
            p = n.next;
        }
        p = head;
        while(p!=null){
            if(p.random != null){
                p.next.random = p.random.next;
            }
            p = p.next.next;
        }
        
        head2 = head.next;
        p = head;
        while(p!=null){
            p2 = p.next;
            p.next = p2.next;
            if (p2.next != null) p2.next = p2.next.next;
            p = p.next; 
        }
        return head2;
    }
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM