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 找到对应的新节点。

相关推荐
All for pursuit.3 分钟前
【分治-2】215.数组中的第K个最大元素
数据结构·c++·算法·leetcode
CQU_JIAKE12 分钟前
9.15【A】
算法·动态规划
成为深度学习高手14 分钟前
DAG:沿时间与通道双相关建模的外生变量时序预测
网络·人工智能·深度学习·算法·机器学习·数据挖掘·时序数据库
阳明山水41 分钟前
CEDAR双重解耦实现决策与干预分离
人工智能·深度学习·算法·机器学习·架构
w_zero_one1 小时前
链表(3)
java·数据结构·算法
Zootopia6261 小时前
美国载人飞船Crew-13明晚发射!
人工智能·算法·机器学习·数学建模·无人机·创业创新·信息与通信
zhangfeng11331 小时前
qjlDim 含义 TurboQuant QJL Quantized Johnson-Lindenstrauss,量化JL随机投影
人工智能·算法·ai编程·npu
HwJack201 小时前
【HarmonyOS开发小实践】HarmonyOS GC 引用计数 vs 对象追踪,三种回收算法
jvm·算法·harmonyos
blxr_1 小时前
力扣hot100前k个高频元素https://leetcode.cn/problems/top-k-frequent-elements/
算法·leetcode·职场和发展
longlongzihan11 小时前
LeetCode 17电话号码的字母组合:回溯算法(DFS)详解
c++·算法·leetcode·深度优先