复制含有随机指针节点的链表

含有随机指针节点,是指这个链表不仅含有next指着,指向下一个节点,还含有rand指针,随机指向本链表中的一个节点,被指向的节点可以在本节点之前,也可以在本节点之后;

本题需要复制这样一个含有随机指针节点的链表。

解1:使用HashMap,时间复杂度为O(N),空间复杂度为O(N)

 1 public class RandNode {
 2     int val;
 3     RandNode rand;
 4     RandNode next;
 5 
 6     public RandNode(int val){
 7         this.val=val;
 8     }
 9 
10 }
View Code
 1 // 复制一个含有随机指针节点的链表
 2 public static RandNode copyListWithRand1(RandNode head){
 3     if(head==null)
 4         return null;
 5     // hashmap将rand指针的next对应关系存起来
 6     HashMap<RandNode, RandNode> nodeMap = new HashMap<RandNode, RandNode>();
 7     RandNode cur = head;
 8     while(cur != null){
 9         nodeMap.put(cur, new RandNode(cur.val));
10         cur = cur.next;
11     }
12     
13     // 建立next和rand的对应关系
14     cur = head;
15     while(cur != null){
16         nodeMap.get(cur).next = nodeMap.get(cur.next);
17         nodeMap.get(cur).rand = nodeMap.get(cur.rand);
18         cur = cur.next;
19     }
20     return nodeMap.get(head);
21 }
View Code

 解2:时间复杂度为O(N),空间复杂度为O(1)

遍历链表,将当前遍历的节点,创建副本copy,将copy链接到当前节点和下一次遍历的节点之间;

将副本节点的rand指针指向正确位置;

拆分原来的链表和新复制的链表;

 1 // 复制一个含有随机指针节点的链表,解法2
 2     public static RandNode copyListWithRand2(RandNode head){
 3         if(head==null)
 4             return head;
 5 
 6         // 先遍历链表,同时复制此链表,将每个节点的副本copy,放在本节点和下一个遍历的节点之间
 7         RandNode cur = head;
 8         while (cur!=null){
 9             RandNode copy = new RandNode(cur.val);
10             copy.next = cur.next;
11             cur.next = copy;
12             cur = copy.next;
13         }
14 
15         // 在遍历链表,将副本的rand指针链接起来
16         cur = head;
17         while(cur != null){
18             if(cur.rand != null){
19                 cur.next.rand = cur.rand.next;
20             }
21             cur = cur.next.next;
22         }
23 
24         // 拆分链表
25         RandNode rs = head.next;
26         RandNode newCur;
27         cur = head;
28 
29         while(cur != null){
30             newCur = cur.next;
31             cur.next = newCur.next;  //下一轮的第一个
32             if(cur.next != null)
33                 newCur.next = cur.next.next;
34             else
35                 newCur.next = null;
36             cur = cur.next;
37         }
38 
39         return rs;
40     }
View Code

 

posted @ 2017-10-28 23:05  Apollo_zhanghongbo  阅读(365)  评论(0编辑  收藏  举报