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-/

  • 相关阅读:
    关闭编辑easyui datagrid table
    sql 保留两位小数+四舍五入
    easyui DataGrid 工具类之 util js
    easyui DataGrid 工具类之 后台生成列
    easyui DataGrid 工具类之 WorkbookUtil class
    easyui DataGrid 工具类之 TableUtil class
    easyui DataGrid 工具类之 Utils class
    easyui DataGrid 工具类之 列属性class
    oracle 卸载
    “云时代架构”经典文章阅读感想七
  • 原文地址:https://www.cnblogs.com/flix/p/13298198.html
Copyright © 2011-2022 走看看