【連結串列問題】打卡8:複製含有隨機指標節點的連結串列

苦逼的碼農發表於2018-12-11

前言

以專題的形式更新刷題貼,歡迎跟我一起學習刷題,相信我,你的堅持,絕對會有意想不到的收穫。每道題會提供簡單的解答,如果你有更優雅的做法,歡迎提供指點,謝謝。

注:如果程式碼排版出現了問題麻煩通知我下,謝謝。

【題目描述】

【連結串列問題】打卡8:複製含有隨機指標節點的連結串列

【要求】

如果連結串列的長度為 N, 時間複雜度達到 O(N)。

【難度】

尉:★★☆☆

【解答】

方法一:使用額外的儲存空間

這道題的難點在於我們需要定位好隨機指標,一個比較簡單的解法就是把原節點與複製的節點關聯起來,可以使用雜湊表把他們關聯起來。

首先把副節點全部建立出來,然後把原節點與對應的副節點用雜湊表關聯起來。關聯的時候原節點作為key,副節點作為value。例如對於連結串列 1->2->3->null。建立副節點 1', 2', 3'。然後用雜湊表關聯起來:

key value
1 1'
2 2'
3 3'

之後在把所有副節點連線成一個連結串列。在連線的時候,我們 可以通過雜湊表很容易這找到對應的隨機節點。

程式碼如下

    //方法1:採用雜湊表
    public static Node1 copyListWithRand(Node1 head) {
        Map<Node1, Node1> map = new HashMap<>();
        Node1 cur = head;
        while (cur != null) {
            map.put(cur, new Node1(cur.value));
            cur = cur.next;
        }
        //把副節點連線起來
        cur = head;
        while (cur != null) {
            map.get(cur).next = map.get(cur.next);
            map.get(cur).rand = map.get(cur.rand);
            cur = cur.next;
        }
        return map.get(head);
    }

這種方法的時間複雜度為 O(n), 空間複雜度也為 O(n)。

方法2

其實我們也可以不需要雜湊表來輔助,也就是說 ,我們是可以做到空間複雜度為 O(1)的,我們可以把複製的副節點插入到原連結串列中去,這樣也能把原節點與副節點進行關聯,進而
定位到隨機節點。例如,對於連結串列 1->2->3->null。首先生成副節點 1', 2', 3。然後把副節點插入到原節點的相鄰位置,即把原連結串列變成 1->1'->2->2'->3->3'->null。

這樣我們也可以在連線副節點的時候,找到相應的隨機節點。例如 1 的隨機節點是 3,則 1' 的隨機節點是 3'。顯然,1節點的隨機節點的下一個節點就是 1'的隨機節點。具體程式碼如下:

    //方法二
    public static Node1 copyListWithRand2(Node1 head){
        Node1 cur = head;
        Node1 next = null;

        //把複製的節點插進去
        while (cur != null) {
            next = cur.next;
            Node1 temp = new Node1(cur.value);//複製節點
            temp.next = cur.next;
            cur.next = temp;
            cur = next;
        }
        //在一邊把複製的節點取出來一邊連線。
        cur = head;
        next = null;
        while (cur != null) {
            next = cur.next.next;//儲存原連結串列的下一個節點
            cur.next.next = next != null ? next.next : null;
            cur.next.rand = cur.rand != null ? cur.rand.next : null;
            cur = next;
        }
        return head.next;
    }

採用這種方法的時候,由於隨機節點有可能是空指標,隨意寫程式碼的時候要注意。

問題擴充

思考:如果是有兩個隨機指標呢?又該如何處理呢?三個呢?

【題目描述】

【要求】

【難度】

未知。

【解答】

提醒:別想太多了,保持清醒。

往期

【連結串列問題】打卡7:將單向連結串列按某值劃分成左邊小,中間相等,右邊大的形式

【連結串列問題】打卡6:三種方法帶你優雅判斷迴文連結串列

【連結串列問題】環形單連結串列約瑟夫問題

最後推廣下我的公眾號:苦逼的碼農,文章都會首發於我的公眾號,期待各路英雄的關注交流。

相關文章