题目要求使用深拷贝,关于浅拷贝和深拷贝参见c++浅拷贝和深拷贝
解析:
利用广度优先搜索,借助队列和哈希表实现,时间复杂度O(n),空间复杂度O(n)
- 哈希表用来存储原始节点和对应的新节点,同时用来判断某个结点是否被访问过
- 广度优先搜索借助队列实现
- 由于是深拷贝,要借助关键词
new
来实现
代码实现
class Solution {
public:
Node* cloneGraph(Node* node) {
if (node == nullptr) {
return node;
}
//哈希表存储原始结点和新结点地址,同时用来判断某个结点是否访问过
unordered_map<Node*, Node*> visited;
queue<Node*> Q;
Q.push(node);
//首结点的位置
visited[node] = new Node(node->val);
while(!Q.empty()) {
Node* n = Q.front();//取出队列第一个结点
Q.pop();
//遍历该节点的邻居
for(auto& neighbor : n->neighbors) {
if(visited.find(neighbor) == visited.end()) {
//如果该节点没有被访问过,更新结点地址,同时加入队列中
visited[neighbor] = new Node(neighbor->val);
Q.push(neighbor);
}
//更新当前结点的邻居,放入的是构造之后的地址
visited[n]->neighbors.emplace_back(visited[neighbor]);
}
}
return visited[node];
}
};
push_back()和emplace_back()的区别
push_back()函数向容器中加入一个临时对象(右值元素)时,首先会调用构造函数生成这个对象,然后调用拷贝构造函数将这个对象放入容器中,最后释放临时对象。而emplace_back()函数向容器中加入临时对象,临时对象原地构造,没有拷贝或移动的操作,所以效率比较高。
图的广度优先搜索都可以借助队列来实现,针对树来说,不需要存储已经访问过的结点,因为树不存在圈。