offer 35 複雜鏈表的賦值

複雜鏈表的賦值

image.png

題目分析

普通鏈表的節點定義以下:node

// Definition for a Node.
class Node {
    int val;
    Node next;
    public Node(int val) {
        this.val = val;
        this.next = null;
    }
}

本題鏈表的節點的定義以下
比普通的鏈表多了一個randomdom

// Definition for a Node.
class Node {
    int val;
    Node next, random;
    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}

就是在複製鏈表的時候還要帶着random
image.png
這個時普通鏈表的複製this

class Solution {
    public Node copyRandomList(Node head) {
        Node cur = head;
        Node dum = new Node(0), pre = dum;
        while(cur != null) {
            Node node = new Node(cur.val); // 複製節點 cur
            pre.next = node;               // 新鏈表的 前驅節點 -> 當前節點
            // pre.random = "???";         // 新鏈表的 「 前驅節點 -> 當前節點 」 沒法肯定
            cur = cur.next;                // 遍歷下一節點
            pre = node;                    // 保存當前新節點
        }
        return dum.next;
    }
}

利用哈希表查表

HashMap 的鍵值對,構建原來的鏈表節點和新鏈表的對應節點的鍵值對映射關係,而後再遍歷next和random引用指向spa

image.png

拼接 + 拆分

image.png
也就是構建新的鏈表爲
node1→node1new→node2→node2 new→⋯
所以當node1指向node2的時候node1new也指向node2new,node1的random指向本身的random的時候,那node1new的random也就只想node1.random.nextcode

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head==null) return null;
        //首先定義舊鏈表的頭節點 
        Node cur = head;
        //複製各個節點構成拼接鏈表
        while(cur!=null){
            Node temp = new Node(cur.val);
            //新鏈表節點的next是當前節點的next
            temp.next = cur.next;
            //當前節點的next是新節點
            cur.next  = temp;
            //繼續便利,下一個節點應該是當前節點的next的next,也就是temp的next
            cur = temp.next;
        }
        //對新拼接的鏈表設置random指向
        cur = head;
        while(cur!=null){
            if(cur.random!=null){
                //下一個節點也就是新節點的隨機等於當前舊節點的隨機的next
                cur.next.random = cur.random.next;
            }
            cur = cur.next.next;
        }
        //指向完畢 對鏈表進行拆分 直接拿頭節點的next就是新鏈表的頭節點
        cur = head.next;
        Node res = head.next;
        Node pre = head;
        while(cur.next!=null){
            pre.next = pre.next.next;
            cur.next = cur.next.next;
            pre = pre.next;//舊鏈表
            cur = cur.next;//新鏈表
        }
        //執行完畢以後,舊鏈表還差一個尾節點的next的null沒加 
        //由於他原本的next應該是新鏈表,可是拆開以後就變成null了
        pre.next = null;
        return res;
    }
}
相關文章
相關標籤/搜索