zoukankan      html  css  js  c++  java
  • 【LeetCode-链表】复制带随机指针的链表

    题目描述

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

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

    我们用一个由 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 = hash[cur->next];
                }
                if(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-/

  • 相关阅读:
    dwz 嵌套网页的搜索刷新问题
    dwz 解决remote验证唯一时缓存问题。
    dwz div 局部刷新
    Oracle 递归查询子节点和父节点 函数方法
    关于未能加载文件或程序集“System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项的解决办法
    CentOS7搭建vsftp服务器
    Linux下 cmatrix的安装和使用(黑客屏保)
    配置动态web服务(wsgi)
    centos7 搭建discuz 全
    Centos7 更换为阿里源
  • 原文地址:https://www.cnblogs.com/flix/p/13298198.html
Copyright © 2011-2022 走看看