leetcode 138 复制随机链表

这个题的难点就在于,复制时,需要找到对应的新的链表,比如10指向1,我们要和新链表的1对应上,就必须要用哈希表做记录,或者用一些手法。

解法一:哈希表

考虑建一个只有next的列表,其实比较简单,但是random要求我们随机访问,所以要存一下老节点对应的新节点。

cpp 复制代码
/*
// 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) {
        Node *dummy = new Node(0), *p = head, *p2 = dummy;
        map<Node*, Node*> s;
        while(p)
        {
            Node *n = new Node(p->val);
            p2->next = n;
            s[p] = n;
            p2 = p2->next;
            p = p->next;
        }

        p = head, p2 = dummy->next;

        while(p)
        {
            if(p->random)
            {
                auto n2 = s[p->random];
                p2->random = n2;
            }
            p = p->next;
            p2 = p2->next;
        }

        return dummy->next;
    }
};

解法二:零空间

既然做链表题,就得要求零空间复杂度,这才是难点,但是这个算法也是真麻烦

首先,先做原数组修改,每个节点后面加上一个复制,这样就可以用核心语句 p->next->random = p->random->next; 来对所有新节点的random节点进行赋值(最难得一步)

然后就是链表分离(最恶心的一步)由于新老链表完全耦合,需要同时进行新老链表的分离操作,新链表用dummy取出,老链表用作遍历,细节比较多

cpp 复制代码
/*
// 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)return nullptr;

        Node *p = head, *tmp;
        while(p)
        {
            tmp = p->next;
            p->next = new Node(p->val);
            p->next->next = tmp;
            p = tmp;
        }

        p = head;
        while(p)
        {
            if(p->random)
            {
                p->next->random = p->random->next;
            }
            p = p->next->next;
        }

        Node *dummy = new Node(0);
        p = dummy;
        Node *p1 = head;
        while(p1)
        {
            p->next = p1->next;
            p = p->next;
            p1->next = p1->next->next;
            p1 = p1->next;
        }

        return dummy->next;
    }
};
相关推荐
海清河晏1112 小时前
数据结构 | 单循环链表
数据结构·算法·链表
wuweijianlove6 小时前
算法性能的渐近与非渐近行为对比的技术4
算法
_dindong6 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
AI成长日志6 小时前
【Agentic RL】1.1 什么是Agentic RL:从传统RL到智能体学习
人工智能·学习·算法
黎阳之光6 小时前
黎阳之光:视频孪生领跑者,铸就中国数字科技全球竞争力
大数据·人工智能·算法·安全·数字孪生
skywalker_116 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia6 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
wfbcg7 小时前
每日算法练习:LeetCode 209. 长度最小的子数组 ✅
算法·leetcode·职场和发展
_日拱一卒7 小时前
LeetCode:除了自身以外数组的乘积
数据结构·算法·leetcode
计算机安禾7 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio