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;
    }
};

 

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