面試題35:複雜連結串列的複製

鹹魚不會游泳發表於2020-12-04

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

方法一:暴力
先構建連結串列,然後再一個一個的找 random 指標所指向的結點

  • 時間複雜度O(n^2)
  • 空間複雜度O(1)

時間效率太差了,完全沒有美感

方法二:空間換時間
用一個大小為 n 的 hash 表儲存,用 O(n) 的空間把時間從 O(n^2) 降到 O(n)

方法三:同步複製
第一趟遍歷構建複製結點,對連結串列中的每一個結點作一個複製,複製結點連結在當前結點之後,複製的結點的 next 為當前結點的下一個結點。

第二趟遍歷,構建 random 指標,複製結點的 random 指標指向,當前結點 random 的下一個結點,同時斷開當前結點和複製結點的連結,就可以得到深拷貝的複雜連結串列了。

  • 指標太亂了,可以多定義幾個防止混淆和空指標判定
  • 時間複雜度O(n)
  • 空間複雜度O(1)
class Solution {
    public Node copyRandomList(Node head) {
        if (head == null ){
            return null;
        }
        Node curr = head;
        //拷貝連結串列,並且把連結串列連線起來
        while(curr != null){
            Node next = curr.next;
            Node copy = new Node(curr.val);
            curr.next = copy;
            copy.next = next;
            curr = next;
        }
        //指定隨即指標
        curr = head;
        while(curr != null){
            Node next = curr.next.next;//原節點的下一個節點
            Node currCopy = curr.next;//當前的拷貝節點
            currCopy.random = curr.random!=null?curr.random.next:null;//指定隨機指標節點
            curr = next;//當前節點指向下一個節點
        }
        //拆分連結串列
        curr = head;
        Node res = curr.next;//用於返回的拷貝頭節點
        while (curr != null){
            Node next = curr.next.next;//原節點的下一個節點
            Node curCopy = curr.next;//拷貝節點
            curr.next = next;//將原節點指向下一個原節點
            curCopy.next = next!=null?next.next:null;//拷貝節點的下一個節點指向下一個原節點的下一個節點
            curr = next;//將當前節點指向下一個原節點
        }
        return res;
    }
}

相關文章