题目:
请实现 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]]
示例2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
代码实现:
/*
// 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 == nullptr) return nullptr;
Node* cur = head;
unordered_map<Node*, Node*> umap;
// step1 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
while(cur != nullptr) {
umap[cur] = new Node(cur->val);
cur = cur->next;
}
cur = head;
// step2 构建新链表的 next 和 random 指向
while(cur != nullptr) {
umap[cur]->next = umap[cur->next];
umap[cur]->random = umap[cur->random];
cur = cur->next;
}
// step3 返回新链表的头节点
return umap[head];
}
};
这道题真的想了好久,前面也尝试用类似的思想:先复制结点,在复制random链接,最后在把新复制的结点从中剥离出来。但是显示超时…
因为之前没有学习过C++中的容器,没想到还有这么好用的东西!
上知识:
unordered_map 是关联容器,含有带唯一键的键(key;it->first)-值(value;it->second) pair 。搜索、插入和元素移除拥有平均常数时间复杂度。
元素在内部不以任何特定顺序排序,而是组织进桶中。元素放进哪个桶完全依赖于其键的哈希。这允许对单独元素的快速访问,因为一旦计算哈希,则它准确指代元素所放进的桶。
unordered_map的模板定义如下:
template < class Key, // unordered_map::key_type
class T, // unordered_map::mapped_type
class Hash = hash<Key>, // unordered_map::hasher
class Pred = equal_to<Key>, // unordered_map::key_equal
class Alloc = allocator< pair<const Key,T> > // unordered_map::allocator_type
> class unordered_map;
- key:键值的类型。unordered_map中的每个元素都是由其键值唯一标识的。
- T:映射值的类型。unordered_map中的每个元素都用来存储一些数据作为其映射值。
这里的umap[cur] = new Node(cur->val);中,key对应cur,T对应新结点new Node(cur->val)。
有关unordered_map的更加详细的介绍参考下面的博客吧~
https://blog.csdn.net/weixin_45745854/article/details/122785542