題目:
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.
題解:
如果要copy一個帶有random pointer的list,主要的問題就是有可能這個random指向的位置還沒有被copy到,所以解決方法都是多次掃描list。
第一種方法,就是使用HashMap來坐,HashMap的key存原始pointer,value存新的pointer。
第一遍,先不copy random的值,只copy數值建立好新的連結串列。並把新舊pointer存在HashMap中。
第二遍,遍歷舊錶,複製random的值,因為第一遍已經把連結串列複製好了並且也存在HashMap裡了,所以只需從HashMap中,把當前舊的node.random作為key值,得到新的value的值,並把其賦給新node.random就好。
程式碼如下:
2 if(head==null)
3 return null;
4 HashMap<RandomListNode,RandomListNode> map = new HashMap<RandomListNode,RandomListNode>();
5 RandomListNode newhead = new RandomListNode(head.label);
6 map.put(head,newhead);
7 RandomListNode oldp = head.next;
8 RandomListNode newp = newhead;
9 while(oldp!=null){
10 RandomListNode newnode = new RandomListNode(oldp.label);
11 map.put(oldp,newnode);
12 newp.next = newnode;
13
14 oldp = oldp.next;
15 newp = newp.next;
16 }
17
18 oldp = head;
19 newp = newhead;
20 while(oldp!=null){
21 newp.random = map.get(oldp.random);
22 oldp = oldp.next;
23 newp = newp.next;
24 }
25
26 return newhead;
27 }
上面那種方法遍歷2次list,所以時間複雜度是O(2n)=O(n),然後使用了HashMap,所以空間複雜度是O(n)。
第二種方法不使用HashMap來做,使空間複雜度降為O(1),不過需要3次遍歷list,時間複雜度為O(3n)=O(n)。
第一遍,對每個node進行復制,並插入其原始node的後面,新舊交替,變成重複連結串列。如:原始:1->2->3->null,複製後:1->1->2->2->3->3->null
第二遍,遍歷每個舊node,把舊node的random的複製給新node的random,因為連結串列已經是新舊交替的。所以複製方法為:
node.next.random = node.random.next
前面是說舊node的next的random,就是新node的random,後面是舊node的random的next,正好是新node,是從舊random複製來的。
第三遍,則是把新舊兩個表拆開,返回新的表即可。
程式碼如下:
2 if(head == null)
3 return head;
4 RandomListNode node = head;
5 while(node!=null){
6 RandomListNode newNode = new RandomListNode(node.label);
7 newNode.next = node.next;
8 node.next = newNode;
9 node = newNode.next;
10 }
11
12 node = head;
13 while(node!=null){
14 if(node.random != null)
15 node.next.random = node.random.next;
16 node = node.next.next;
17 }
18
19 RandomListNode newHead = head.next;
20 node = head;
21 while(node != null){
22 RandomListNode newNode = node.next;
23 node.next = newNode.next;
24 if(newNode.next!=null)
25 newNode.next = newNode.next.next;
26 node = node.next;
27 }
28 return newHead;
29 }
Reference:http://blog.csdn.net/linhuanmars/article/details/22463599