1. 程式人生 > >Copy List with Random Pointer 解題報告

Copy List with Random Pointer 解題報告

Copy List with Random Pointer

Description

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.

Challenge

Could you solve it with O(1) space?

實現思路一:基於雜湊表

常規思路是我們可以維護一個雜湊表,需要額外O(n)的空間複雜度。
每次複製的時候,將其隨機節點作為鍵存到hash表中,值為新複製的節點。
如此迴圈一遍後,我們得到個依次連線的新的連結串列,同時一個對應的雜湊表。
第二次同時對新舊連結串列進行遍歷,每次以舊連結串列節點的隨機節點(如果不存在,則不做任何操作)作為健,查詢雜湊表對應的的值(新連結串列節點),作為當前遍歷到的新連結串列節點的隨機節點。
根據此思路,求解方法如下:

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    /**
     * @param head: The head of linked list with a random pointer.
     * @return
: A new head of a deep copy of the list. */
public RandomListNode copyRandomList(RandomListNode head) { // write your code here if(head == null){ return null; } HashMap<RandomListNode,RandomListNode> map = new HashMap<>(); RandomListNode behead = head,newhead = new
RandomListNode(-1),benewhead = newhead; while(head != null){ RandomListNode newNode = new RandomListNode(head.label); newhead.next = newNode; newhead = newhead.next; map.put(head,newhead); head = head.next; } head = behead; newhead = benewhead.next; while(head != null){ if(head.random != null){ newhead.random = map.get(head.random); } head = head.next; newhead = newhead.next; } return benewhead.next; } }

實現思路二:基於複製連結串列

思路一我們使用了額外的雜湊表來儲存對映關係,但利用相似的思路,結合連結串列的特性,我們可以去掉雜湊表,將雜湊表中oldnode->newnode的對映直接放到連結串列中。
假設原來節點為:
oldnode1->oldnode2->oldnode3->oldnde4
現在變成
oldnode1->newnode1->oldnode2->newnde2->oldnode4->newnode3->oldnode5->newnde4
當需要設定隨機節點時,我們只需利用類似於雜湊表的思路:newnode.random = map.get(head.random)
對於到這個新的“融合連結串列”中,就是:
oldnode.next.random = oldnode.random.next
這裡注意做恆等比較,即:
1. oldnode.next(.random) = newnode(.random)
2. map.get(oldnode.random) = oldnode.random.next

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    /**
     * @param head: The head of linked list with a random pointer.
     * @return: A new head of a deep copy of the list.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here
        if(head == null){
            return null;
        }
        RandomListNode behead = head;
        while(head != null){
            RandomListNode newNode = new RandomListNode(head.label);
            newNode.next = head.next;
            head.next = newNode;
            head = newNode.next;
        }
        head = behead;
        while(head != null){
            if(head.random != null){
                head.next.random = head.random.next;
            }
            head = head.next.next;
        }
        head = behead.next;
        while(head.next != null){
            head.next = head.next.next;
            head = head.next;
        }
        return behead.next;
    }
}