PS義大利稱:就快開始了 或暗示索尼下一場釋出會
阿新 • • 發佈:2021-07-01
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. 結語
努力去愛周圍的每一個人,付出,不一定有收穫,但是不付出就一定沒有收穫! 給街頭賣藝的人零錢,不和深夜還在擺攤的小販討價還價。願我的部落格對你有所幫助(*^▽^*)(*^▽^*)!
如果客官喜歡小生的園子,記得關注小生喲,小生會持續更新(#^.^#)(#^.^#)。
但行好事 莫問前程