劍指offer之複雜鏈表的複製(C++/Java雙重實現)

1.題目描述

請實現 copyRandomList 函數,複製一個複雜鏈表。在複雜鏈表中,每個節點除了有一個 next 指針指向下一個節點,還有一個 random 指針指向鏈表中的任意節點或者 null。
事例1:
在這裏插入圖片描述輸入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
輸出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
事例2:
在這裏插入圖片描述
輸入:head = [[1,1],[2,1]]
輸出:[[1,1],[2,1]]
事例3:
在這裏插入圖片描述輸入:head = [[3,null],[3,0],[3,null]]
輸出:[[3,null],[3,0],[3,null]]
事例4:
輸入:head = []
輸出:[]
解釋:給定的鏈表爲空(空指針),因此返回 null。
注意:
-10000 <= Node.val <= 10000
Node.random 爲空(null)或指向鏈表中的節點。
節點數目不超過 1000 。

在這裏插入圖片描述

2.題目分析

在這裏插入圖片描述

3.代碼實現

3.1C++代碼:
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(head==NULL)
            return NULL;
        Node* head1=head;
        //複製備份所有節點
        while(head1!=NULL)
        {
            Node* newnode=new Node(head1->val);
            newnode->next=head1->next;
            head1->next=newnode;
            head1=newnode->next;//移動節點指針
        }
        //更新每個備份節點的指針指向
        head1=head;
        while(head1!=NULL)
        {
            Node* randmnode=head1->random;
            if (head1->random!=NULL)//一定要判斷是否爲空,只有非空節點才能操作,切記
				head1->next->random = randmnode->next;
            head1=head1->next->next;//移動節點指針,一次性跳躍兩個節點
        }
        //分離兩個鏈表
        head1=head;
        Node* head2=new Node(-1);
        Node* curp=head2;
        while(head1!=NULL)
        {
            Node* nextnode=head1->next;
            curp->next=nextnode;
            head1->next=nextnode->next;//重新連接next指針
            head1=head1->next;//移動head1節點指針
            curp=nextnode;//移動curp節點指針
        }
        return head2->next;
    }
};

這裏注意:原鏈表不能銷燬

3.1Java代碼:
/*
// 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 head1=head;
        //複製備份所有節點
        while(head1!=null)
        {
            Node newnode=new Node(head1.val);
            newnode.next=head1.next;
            head1.next=newnode;
            head1=newnode.next;//移動節點指針
        }
        //更新每個備份節點的指針指向
        head1=head;
        while(head1!=null)
        {
            Node randmnode=head1.random;
            if (head1.random!=null)//一定要判斷是否爲空,只有非空節點才能操作,切記
				head1.next.random = randmnode.next;
            head1=head1.next.next;//移動節點指針,一次性跳躍兩個節點
        }
        //分離兩個鏈表
        head1=head;
        Node head2=new Node(-1);
        Node curp=head2;
        while(head1!=null)
        {
            Node nextnode=head1.next;
            curp.next=nextnode;
            head1.next=nextnode.next;//重新連接next指針
            head1=head1.next;//移動head1節點指針
            curp=nextnode;//移動curp節點指針
        }
        return head2.next;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章