leetcode 138随机链表的复制

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:
    unordered_map<Node*,Node*>cacheNode;
    Node* copyRandomList(Node* head) {
        Node *p = head;
        while(p!=nullptr){
            cacheNode[p] = new Node(p->val);
            p = p->next;
        }
        p = head;
        while(p!=nullptr){
            cacheNode[p]->next = cacheNode[p->next];
            cacheNode[p]->random = cacheNode[p->random];
            p = p->next;
        }
        return   cacheNode[head];
    }
};

这题的方法可以精简成一句话:

先用哈希表建立"原节点 → 新节点"的映射,再根据原链表的 next 和 random 去连接新链表。

方法流程:

复制代码
// 第一遍:创建新节点
while (p != nullptr) {
    cacheNode[p] = new Node(p->val);
    p = p->next;
}

// 第二遍:连接 next 和 random
p = head;
while (p != nullptr) {
    cacheNode[p]->next = cacheNode[p->next];
    cacheNode[p]->random = cacheNode[p->random];
    p = p->next;
}

核心映射关系要记住:

复制代码
原节点 p         -> cacheNode[p]

原 p->next       -> cacheNode[p->next]

原 p->random     -> cacheNode[p->random]

易错点

最容易错的是第二遍写成:

复制代码
cacheNode[p]->next = p->next;       // 错
cacheNode[p]->random = p->random;   // 错

这样新节点又指回原链表了,不是深拷贝。

必须写:

复制代码
cacheNode[p]->next = cacheNode[p->next];
cacheNode[p]->random = cacheNode[p->random];

第二个易错点是:

复制代码
cacheNode[p] = new Node(p->val);

这里只复制了:

复制代码
val

还没有复制 next 和 random,所以必须有第二遍连接。

第三个易错点是理解:

复制代码
cacheNode[p->random]

它不是 random 本身,而是:

原 random 节点对应的新节点。

比如:

复制代码
A.random -> C

那么:

复制代码
cacheNode[A]->random = cacheNode[C];

得到:

复制代码
A'.random -> C'

复杂度

两次遍历都是 O(n):

复制代码
时间复杂度:O(n)

哈希表存了 n 个映射:

复制代码
空间复杂度:O(n)

最后可以直接背这个模板:

复制代码
unordered_map<Node*, Node*> map;

// 1. 创建
map[原节点] = 新节点;

// 2. 连接
map[p]->next = map[p->next];
map[p]->random = map[p->random];

// 3. 返回
return map[head];

口诀:

第一遍造节点,第二遍连关系;所有旧指针,都要通过 map 找到对应的新节点。

相关推荐
CV爱数码42 分钟前
论文精读|Learned Primal-Dual:把原始–对偶算法展开成网络
图像处理·算法·计算机视觉·ct·重建·断层扫描
yuniko-n1 小时前
【算法】约瑟夫环问题
java·算法
l1t1 小时前
测试DuckDB v2.1.0-alpha49002的bignum乘法
数据库·sql·算法·duckdb
Nil2081 小时前
LeetCode 283移动零
数据结构·算法·leetcode
CQU_JIAKE2 小时前
10.18【A】
算法
LMT流氓兔2 小时前
第五单元——第4课:给工具参数加校验
java·前端·算法·ai·langchain
文丑颜不良啊3 小时前
LeetCode226~250题目解析
java·leetcode
物联网软硬件开发-轨物科技3 小时前
【轨物方案】深度解读开关柜智能感知及一键顺控专家系统
大数据·运维·网络·人工智能·算法·机器人
行者全栈架构师3 小时前
我用 TRAE Work 把桌游之夜搬进了浏览器:一个计分器的从创意到上线
前端·算法·架构
YFJ_mily3 小时前
【10-12月优质学术会议合集】会议覆盖人工智能、大数据、高端装备、软件与网络安全 、计算机视觉技术等热门方向
算法·安全·web安全·网络安全·软件·rdlink研发家