1. 程式人生 > 遊戲 >PS義大利稱:就快開始了 或暗示索尼下一場釋出會

PS義大利稱:就快開始了 或暗示索尼下一場釋出會

1. 題目

請實現 copyRandomList 函式,複製一個複雜連結串列。在複雜連結串列中,每個節點除了有一個 next 指標指向下一個節點,還有一個 random 指標指向連結串列中的任意節點或者 null。

2. 示例

示例1:

輸入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
輸出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例2:

輸入:head = [[1,1],[2,1]]
輸出:[[1,1],[2,1]]

示例3:

輸入:head = [[3,null],[3,0],[3,null]]
輸出:[[3,null
],[3,0],[3,null]]

示例4:

輸入:head = []
輸出:[]
解釋:給定的連結串列為空(空指標),因此返回 null

提示:

-10000 <= Node.val <= 10000
Node.random 為空(null)或指向連結串列中的節點。
節點數目不超過 1000 

3. 題解

本題給出了兩種解題思路:

  • HashMap
    • 建立Hash表,key為原節點,value為新節點。
    • 在Hash表中遍歷key,就可以不斷的獲取新節點: map.get(cur)。讓其next指向map.get(cur.next)節點即可,同樣的,讓random指向map.get(cur.random)即可。
    • 返回map.get(head)就是返回的新連結串列的頭結點。
  • 拼接+拆分
    • 需要遍歷三次
    • 第一次遍歷建立拼接連結串列:原節點1->新節點1->原節點2->新節點2,這樣的拼接連結串列。此時還未引入random。
    • 第二次遍歷建立random指向:始終存在一個順序,就是新節點的next一定在原節點中next指向的next節點的後面,新節點的random一定在原節點random指向的andom節點的後面。
    • 第三次遍歷拆分拼接年連結串列

4. 實現

4.1 HashMap

 1 public class CopyRandomList35 {
 2     // HashMap
3 public Node copyRandomListA(Node head) { 4 if(head == null) return null; 5 Node cur = head; 6 // HashMap<Key, value>,key:原節點,value:新節點。 7 Map<Node, Node> map = new HashMap<>(); 8 // 遍歷各節點,簡歷“原節點->新節點”的Map對映 9 while (cur != null) { 10 map.put(cur, new Node(cur.val)); 11 cur = cur.next; 12 } 13 cur = head; 14 // 遍歷map,建立新連結串列 15 while (cur != null) { 16 map.get(cur).next = map.get(cur.next); 17 map.get(cur).random = map.get(cur.random); 18 cur = cur.next; 19 } 20 // 返回新連結串列的頭結點 21 return map.get(head); 22 } 23 }
View Code

4.2 拼接+拆分

 1 public class CopyRandomList35 {
 2     // 拼接+拆分
 3     public Node copyRandomListB(Node head) {
 4         // 如果為空,直接返回
 5         if(head == null) return null;
 6         Node cur = head;
 7         // 1. 第一輪遍歷,建立只包含next的拼接連結串列
 8         // 新連結串列結構:原節點1->新節點1->原節點2->新節點2
 9         while (cur != null) {
10             Node temp = new Node(cur.val);
11             temp.next = cur.next;
12             cur.next = temp;
13             cur = temp.next;
14         }
15         // 2. 第二輪遍歷,建立random指向
16         cur = head;
17         while (cur != null) {
18             // 原節點的random不為Null,說明存在,那麼新節點的random需要指向原節點的random的下一個節點。
19             if(cur.random != null) {
20                 cur.next.random = cur.random.next;
21             }
22             cur = cur.next.next;
23         }
24         cur = head.next;
25         Node pre = head, res = head.next;
26         // 3. 第三輪遍歷,拆分連結串列
27         while(cur.next != null) {
28             pre.next = pre.next.next;
29             cur.next = cur.next.next;
30             pre = pre.next;
31             cur = cur.next;
32         }
33         pre.next = null;
34         return res;
35     }
36 }
View Code

5. 結語

  努力去愛周圍的每一個人,付出,不一定有收穫,但是不付出就一定沒有收穫! 給街頭賣藝的人零錢,不和深夜還在擺攤的小販討價還價。願我的部落格對你有所幫助(*^▽^*)(*^▽^*)!

  如果客官喜歡小生的園子,記得關注小生喲,小生會持續更新(#^.^#)(#^.^#)。

但行好事 莫問前程