码迷,mamicode.com
首页 > 其他好文 > 详细

【LeetCode-链表】复制带随机指针的链表

时间:2020-07-14 11:44:49      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:order   pointer   增加   copy   init   lan   map   ems   def   

题目描述

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的?深拷贝。

我们用一个由?n?个节点组成的链表来表示输入/输出中的链表。每个节点用一个?[val, random_index]?表示:

  • val:一个表示?Node.val?的整数。
  • random_index:随机指针指向的节点索引(范围从?0?到?n-1);如果不指向任何节点,则为??null?。

示例:
技术图片

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

题目链接: https://leetcode-cn.com/problems/copy-list-with-random-pointer/

思路1

分 3 步:
第 1 步,复制链表中的每个节点并放在该节点的后面
技术图片

我们发现:

  • 原节点 1 的随机指针指向原节点 3,新节点 1 的随机指针指向的是原节点 3 的next;
  • 原节点 3 的随机指针指向原节点 2,新节点 3 的随机指针指向的是原节点 2 的next;

也就是也就是,原节点 i 的随机指针(如果有的话),指向的是原节点 j,那么新节点 i 的随机指针,指向的是原节点 j 的 next;
所以,第 2 步就是遍历链表,假设当前结点为 cur,则 cur->next->random = cur->random->next(如果 cur->random!=nullptr);

第 3 步就是把 2 个链表分开
技术图片

/*
// 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==nullptr) return head;

        /*第1步:将复制的节点放在当前节点后面*/
        Node* cur = head;
        while(cur!=nullptr){
            Node* copy = new Node(cur->val);
            copy->next = cur->next;
            cur->next = copy;
            cur = cur->next->next;
        }

        /*第2步:设置复制的节点的random指针*/
        cur = head;
        while(cur!=nullptr){
            if(cur->random!=nullptr) cur->next->random = cur->random->next;
            cur = cur->next->next;
        }

        /*第3步:分类两个链表*/
        Node* dummy = new Node(0);
        dummy->next = head;
        cur = dummy;
        Node* p = head;
        while(p!=nullptr){
            cur->next = p->next;
            cur = cur->next;
            p->next = cur->next;
            p = p->next;
        }
        return dummy->next;
    }
};

思路2

使用哈希表来做,哈希表为 unordered_map<Node*, Node*> hash,hash[node] = copy,也就是节点 node 对应它的拷贝 copy
技术图片

因为节点和其拷贝是一一对应的,我们发现:

  • hash[cur]->next 就是 hash[cur->next];
  • hash[cur]->random 就是 hash[cur->random];

所以,我们先建立哈希表,然后遍历设置 next 和 random。

代码如下:

/*
// 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==nullptr) return head;

        unordered_map<Node*, Node*> hash;
        Node* cur = head;
        while(cur!=nullptr){
            Node* copy = new Node(cur->val);
            hash[cur] = copy;
            cur = cur->next;
        }

        cur = head;
        Node* newHead = hash[cur];
        while(cur!=nullptr){
            if(cur->next!=nullptr && hash[cur->next]!=nullptr){
                hash[cur]->next = hash[cur->next];
            }
            if(cur->random!=nullptr && hash[cur->random]!=nullptr){
                hash[cur]->random = hash[cur->random];
            }
            cur = cur->next;
        }
        return newHead;
    }
};

参考

https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/liang-chong-shi-xian-tu-jie-138-fu-zhi-dai-sui-ji-/

【LeetCode-链表】复制带随机指针的链表

标签:order   pointer   增加   copy   init   lan   map   ems   def   

原文地址:https://www.cnblogs.com/flix/p/13298198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!