1. 程式人生 > 實用技巧 >劍指25.複雜連結串列的複製

劍指25.複雜連結串列的複製

題目描述

輸入一個複雜連結串列(每個節點中有節點值,以及兩個指標,一個指向下一個節點,另一個特殊指標random指向一個隨機節點),請對此連結串列進行深拷貝,並返回拷貝後的頭結點。(注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空)

思路

思路1:先複製結點,用next連結,最後根據原始結點的random指標確定該random結點距離頭結點的位置,從而對複製結點設定random指標。但是該思路對於n個結點的連結串列,定位每個節點的random都需要從連結串列頭節點開始經過O(n)步才能找到,所以時間複雜度為O(n^2)。 (時間主要花費在定位節點的random上) 思路2:
複製原始結點N建立N’,用next連結。將<N,N'>的配對資訊存放入一個雜湊表中;在設定random時,通過雜湊表,只需要用O(1)的時間即可找到複製結點的random。該方法的時間複雜度為O(n),但空間複雜度為O(n)。 (相當於空間換時間)
思路3:不用輔助空間的情況下,實現O(n)的時間效率。該方法分為三個步驟。 第一步:複製原始連結串列的任意節點N並建立新節點N',再把N'連結到N的後面

第二步:把複製的節點的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; } }

解法2(對應思路2)