1485. Clone Binary Tree With Random Pointer
1490. Clone N-ary Tree
138. Copy List with Random Pointer
133. Clone Graph
今天连续刷了几道和deep clone有关的题目。
总结下这类题目的通用解题方法。
1. 遍历每个node,同时new 出新的node。 把original node 和 cloned Node 通过 unorder_map 绑定起来。
2. 遍历完所有的orignal node,也就clone完了所有的node。
那下一步就是填充指针了。通过unorder_map 找到clone的新node,按照原始node之前的指针关系填充好新的指针就好了。
对于1485. Clone Binary Tree With Random Pointer,应该也可以用递归来实现,从根往叶子走的时候new Node,到根部后往根退的时候更新指针。
想法很丰满,显示很骨感。
当递归做的时候,并不能保证返回的时候所有节点都克隆完了。
比如左子树正在回退中,右子树还没有访问那。也就是说左子树正在递归退出,右子树还没有克隆。而random指针是有可能指向右子树的节点的。
于是就得同时递归left,right,random节点,并且还得检查节点是否已经访问过了。因为rondom指针随意指向的。
/**
* Definition for a Node.
* struct Node {
* int val;
* Node *left;
* Node *right;
* Node *random;
* Node() : val(0), left(nullptr), right(nullptr), random(nullptr) {}
* Node(int x) : val(x), left(nullptr), right(nullptr), random(nullptr) {}
* Node(int x, Node *left, Node *right, Node *random) : val(x), left(left), right(right), random(random) {}
* };
*/
class Solution {
public:
unordered_map<Node*, NodeCopy*> mymap;
NodeCopy* copyRandomBinaryTree(Node* root) {
if(root == NULL)
return NULL;
if(mymap.find(root) == mymap.end()) {
mymap[root] = new NodeCopy({root->val,NULL, NULL, NULL});
mymap[root]->left = copyRandomBinaryTree(root->left);
mymap[root]->right = copyRandomBinaryTree(root->right);
mymap[root]->random = copyRandomBinaryTree(root->random);
}
return mymap[root];
}
};
133 clone graph
代码如下
/*
// Definition for a Node.
class Node {
public:
int val;
vector<Node*> neighbors;
Node() {
val = 0;
neighbors = vector<Node*>();
}
Node(int _val) {
val = _val;
neighbors = vector<Node*>();
}
Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
*/
class Solution {
public:
Node* cloneGraph(Node* node) {
if(node == NULL)
return NULL;
unordered_map<Node*, Node*> mymap;
queue<Node*> myqueue;
myqueue.push(node);
mymap.insert({node, new Node(node->val, {})});
while(!myqueue.empty()) {
Node* tmp = myqueue.front();
myqueue.pop();
for(auto & neighbor: tmp->neighbors) {
if(mymap.find(neighbor) != mymap.end())
continue;
else {
myqueue.push(neighbor);
mymap.insert({neighbor, new Node(neighbor->val, {})});
}
}
}
for(auto & it: mymap) {
for(auto & neighbor: it.first->neighbors) {
Node * newNodeNeigbor = mymap[neighbor];
it.second->neighbors.push_back(newNodeNeigbor);
}
}
return mymap[node];
}
};