【三次优化】剑指 Offer 35. 复杂链表的复制
立志用最少代碼做最高效的表達
請實現 copyRandomList 函數,復制一個復雜鏈表。在復雜鏈表中,每個節點除了有一個 next 指針指向下一個節點,還有一個 random 指針指向鏈表中的任意節點或者 null。
示例 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 。
思路一:HashMap
思路:以map將新節點和舊節點映射起來,進而建立鏈表。
步驟:
1、完成以next指針為串聯的鏈表的建立,并建立HashMap映射
2、完成random的鏈表建設
缺點:冗余
思路2:對思路1的優化
拆分成兩步:
1、將新舊節點映射起來
2、進行next和random的鏈表建立
時間復雜度:O(n) 、 空間復雜度:O(n)
代碼3:原地復制
思路:在原鏈表的每個節點后都構建一個新節點,將原來形如A->B->C的鏈表改為A->A'->B->B'->C->C',然后拆分兩鏈表即可。
步驟:
1、復制各個節點,構建拼接鏈表
2、構建各個新節點的random指針
3、拆分成兩個鏈表
注意:本題的題意是深拷貝,即不能更改原鏈表。
class Solution {public Node copyRandomList(Node head) {if(head == null) return null;Node cur = head;// 1. 復制各節點,并構建拼接鏈表while(cur != null) {Node tmp = new Node(cur.val);tmp.next = cur.next;cur.next = tmp;cur = tmp.next;}// 2. 構建各新節點的 random 指向cur = head;while(cur != null) {if(cur.random != null)cur.next.random = cur.random.next;cur = cur.next.next;}// 3. 拆分兩鏈表cur = head.next;Node pre = head, res = head.next;while(cur.next != null) {pre.next = pre.next.next;cur.next = cur.next.next;pre = pre.next;cur = cur.next;}pre.next = null; // 單獨處理原鏈表尾節點return res; // 返回新鏈表頭節點} }總結
以上是生活随笔為你收集整理的【三次优化】剑指 Offer 35. 复杂链表的复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剑指 Offer 34. 二叉树中和为某
- 下一篇: 【击败时间100%】剑指 Offer 3