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;
}
}