简介:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
(链表中每个节点含有一个随机的指针)
思路:
利用回溯和哈希表
如果直接按照遍历的顺序创建链表节点,当我们拷贝节点时,当前节点的随机指针指向的节点可能还没创建我们利用回溯的方式,让每个节点的拷贝操作相互独立。对于当前节点,我们首先要进行拷贝,然后我们进行「当前节点的后继节点」和「当前节点的随机指针指向的节点」拷贝,拷贝完成后将创建的新节点的指针返回,即可完成当前节点的两指针的赋值。
我们可以利用哈希表来记录每一个节点对应的新节点的创立情况,从头开始遍历链表,检查当前节点next和random指针所对应的节点是否被创立如果这两个节点中的任何一个节点的新节点没有被创建,我们都立刻递归地进行创建。当我们拷贝完成,回溯到当前层时,我们即可完成当前节点的指针赋值。
因为同一个节点可能被多个指针同时指向,所以为了避免重复创立节点,我们需要判断当前节点是否被创立。
代码如下:
//注意包含头文件,不然不能使用哈希表
#include<unordered_map>
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
using namespace std;
class Solution {
public:
unordered_map<Node*, Node*>cachedNode;
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return nullptr;
}
//count函数是检验头节点对应的新节点是否创立,防止重复创立节点
if (!cachedNode.count(head)) {
Node* headNew = new Node(head->val);
//将新创立的头节点和旧的头节点对应
cachedNode[head] = headNew;
headNew->next = copyRandomList(head->next);
headNew->random = copyRandomList(head->random);
}
return cachedNode[head];
}
};
下面对unorder_map的用法来进行介绍:
利用哈希函数,通过哈希值能快速的查找到所需元素。unordered_map便是采用这种数据结构实现,unordered _map与map的使用基本一样,都是key/value之间的映射,只是他们内部采用的数据结构不一样。
1.unordered_map是一个将key和value关联起来的容器,它可以高效的根据单个key值查找对应的value。
2.key值应该是唯一的,key和value的数据类型可以不相同。
3.unordered_map存储元素时是没有顺序的,只是根据key的哈希值,将元素存在指定位置,所以根据key查找单个value时非常高效,平均可以在常数时间内完成。
4.可以使用[]操作符来访问key值对应的value值。
比如上面的cachedNode[head] = headNew;
5.std::unordered_map<std::string, std::int> umap; //定义
前一个为key值,后一个为value.
unordered_map类模板成员函数: