剑指 35 复杂链表的复制
全部刷题与学习记录
原题目
题目地址:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
请实现 copyRandomList
函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next
指针指向下一个节点,还有一个 random
指针指向链表中的任意节点或者 null
。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
考查知识点
哈希表、链表
好的解法
果然又是一道没能读明白的题。相比于传统的单链表只有一个next
指针指向下一个节点,这道题多了一个random
指针,它的指向不确定。复制一个复杂链表不好想,那么就先来想一下简单的单链表怎么复制。
简单链表的复制分为以下两步:
1 对于每一个旧链表的节点,在内存中开辟一块新的内存空间,即新建一个同样类型的变量
2 按照旧链表的指向next,为新链表的每一个节点设置同样的指向
那么复杂链表比简单链表多了一个random
指针就体现在第2步中除了为新链表节点设置next
,还要设置random
下面是复制复杂链表的逻辑思路:
class Solution {
public:
Node* copyRandomList(Node* head) {
//1 输入检查
//2 根据旧节点新建新节点
//3 按照旧节点指向(next和random)设置新节点的指向
//4 返回新节点的头结点
}
};
下一步就是对于数据结构的敏感度了,怎么样根据旧节点的指向为新节点设置指向呢?
https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
这篇力扣题解中,使用了哈希法来保存旧节点与新节点,这样就保存了新旧节点的对应关系,直接使用哈希表的映射来找到旧节点对应的新节点。
class Solution
{
public:
Node* copyRandomList(Node* head)
{
//1 输入检查
if (!head) return nullptr;
//2 将旧节点与新节点放入哈希表
unordered_map<Node*, Node*> map = {};
Node* cur = head;
while (cur)
{
map[cur] = new Node(cur->val);
cur = cur->next;
}
//3 按照哈希表中旧节点的指向设置新节点指向
cur = head;
while (cur)
{
map[cur]->next = map[cur->next]; //等号左边map[]:新节点的指向 等号右边map[]:新节点
map[cur]->random = map[cur->random];
cur = cur->next;
}
//4 返回新链表头结点
return map[head];
}
};