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];
    }
};

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

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

方法流程:

复制代码
// 第一遍:创建新节点
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

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

第三个易错点是理解:

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

相关推荐
疯狂打码的少年3 小时前
【数据结构】图的遍历:深度优先搜索(DFS)
数据结构·笔记·算法·深度优先
-凌凌漆-4 小时前
【freertos】Task创建(v2)
java·开发语言·算法
Nil2084 小时前
leetcode 24两两交换链表中的节点
算法·leetcode·链表
.格子衫.4 小时前
033动态规划之状态压缩DP——算法备赛
算法·动态规划
ysa0510304 小时前
c++常用自带函数用法与注意
c++·笔记·算法
带多刺的玫瑰6 小时前
Leecode#4刷题之寻找两个正序数组的中位数
java·前端·算法
土司大王6 小时前
LeetCode hot100——除了自身以外数组的乘积
数据结构·算法·leetcode
IvanCodes6 小时前
RAG 实战教程(三):向量数据库检索算法,KNN、IVF、HNSW 与 Faiss 实战
人工智能·算法·agent