LeetCode:138. 複製帶隨機指針的鏈表

一、問題描述

給定一個鏈表,每個節點包含一個額外增加的隨機指針,該指針可以指向鏈表中的任何節點或空節點。

二、解題思路

第一種:用hashmap,遍歷鏈表然後把它存到 HashMap 中,val 作爲 key,Node 作爲 value。遍歷第二遍鏈表,將之前生成的節點取出來,更新它們的 next 和 random 指針。查找複雜度爲 O(1) ,這樣可以把總時間複雜度降到 O(n) ,由於要暫存所有節點,其空間複雜度爲 O(n)。

第二種:三次遍歷得到結果,先把每個節點拷貝,並把拷貝節點連接到原節點後面,依次類推。確定隨機節點的關係之後再拆分鏈表。

三、代碼實現

第一種:

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

    Node() {}

    Node(int _val, Node* _next, Node* _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if (head == nullptr) {
            return head;
        }
        Node *cur = head;
        map<Node*, Node*> map;
        //1. 遍歷鏈表,將原節點作爲key,拷貝節點作爲value保存在map中
        while (cur != nullptr) {
            //原來是1->2->3->4,現在map中存入的是[1,1],[2,2],[3,3],[4,4]
            Node *copy = new Node(cur->val);
            map[cur] = copy;
            cur = cur->next;
        }
        //2. 複製鏈表next和random指針
        //1的random是3;2和3的爲空;4的是2
        cur = head;
        while (cur != nullptr) {//以1爲例
            //1->2
            map[cur]->next = map[cur->next];
            //1 random->3
            map[cur]->random = map[cur->random];
            //下一個結點
            cur = cur->next;
        }
        return map[head];
    }
};

第二種:

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if (head == nullptr) {
            return head;
        }
        Node *node = head;
        //1. 將複製節點添加到原節點後面:1->1->2->2->3->3->4->4
        while (node != nullptr) {
            Node *copy = new Node(node->val, nullptr, nullptr);
            copy->next = node->next;
            node->next = copy;
            node = copy->next;
        }
        
        //2. 複製random節點
        node = head;
        while (node != nullptr) {
            if (node->random != nullptr) {//以1爲例
                //第二個1指向3
                node->next->random = node->random->next;
            } 
            //走兩步           
            node = node->next->next;
        }
        
        //3. 分離鏈表(將鏈表斷開成1->2->3->4,此時之前第二個1、2、3、4都已經爲random了)
        node = head;
        Node *newHead = head->next;
        Node *newNode = newHead;
        while (node != nullptr) {
            node->next = node->next->next;     
            if (newNode->next != nullptr) {
                newNode->next = newNode->next->next;            
            }            
            node = node->next;
            newNode = newNode->next;
        }
        return newHead;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章