劍指25.複雜連結串列的複製
阿新 • • 發佈:2020-08-14
題目描述
輸入一個複雜連結串列(每個節點中有節點值,以及兩個指標,一個指向下一個節點,另一個特殊指標random指向一個隨機節點),請對此連結串列進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空)思路
思路1:先複製結點,用next連結,最後根據原始結點的random指標確定該random結點距離頭結點的位置,從而對複製結點設定random指標。但是該思路對於n個結點的連結串列,定位每個節點的random都需要從連結串列頭節點開始經過O(n)步才能找到,所以時間複雜度為O(n^2)。 (時間主要花費在定位節點的random上) 思路2:第二步:把複製的節點的random指標指向被複制節點的random指標的下一個節點
第三步:拆分成兩個連結串列,奇數位置為原連結串列,偶數位置為複製連結串列,注意複製連結串列的最後一個結點的next指標不能跟原連結串列指向同一個空結點None,next指標要重新賦值None(判定程式會認定你沒有完成複製)
解法1(對應思路3)
/* public class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } } */ public class Solution { public RandomListNode Clone(RandomListNode pHead) { if (pHead == null) return null; cloneNodes(pHead); // 複製節點 connectRandomNodes(pHead); // 設定random return reconnectNodes(pHead); // 拆分長連結串列 } // 第一步:複製每個結點,並插入到原始節點的後面 private void cloneNodes(RandomListNode pHead){ RandomListNode currentNode = pHead; while (currentNode != null){ RandomListNode cloneNode = new RandomListNode(currentNode.label); cloneNode.next = currentNode.next; cloneNode.random = null; currentNode.next = cloneNode; currentNode = cloneNode.next; } } // 第二步:根據原節點的random,設定複製節點的random private void connectRandomNodes(RandomListNode pHead){ RandomListNode currentNode = pHead; while (currentNode != null){ if (currentNode.random != null) currentNode.next.random = currentNode.random.next; // 指向原始節點random指向的下一個節點 currentNode = currentNode.next.next; } } // 第三步:將長連結串列拆分成原始連結串列和複製連結串列(根據奇偶位置) private RandomListNode reconnectNodes(RandomListNode pHead){ RandomListNode currentNode = pHead; RandomListNode pCloneHead = pHead.next; while (currentNode != null){ RandomListNode pCloneNode = currentNode.next; if (pCloneNode.next != null){ currentNode.next = pCloneNode.next; pCloneNode.next = currentNode.next.next; }else{ currentNode.next = null; pCloneNode.next = null; } currentNode = currentNode.next; } return pCloneHead; } }