leetcode deepclone

这篇博客探讨了如何解决一系列涉及深度克隆的编程问题,包括二叉树、N叉树和图的克隆。通用方法是遍历原始节点,创建新节点并使用哈希映射进行关联,然后填充新节点的指针。在处理具有随机指针的二叉树时,递归方法可能会遇到挑战,因为可能在回溯时未完成所有节点的克隆。为了解决这个问题,需要同时处理当前节点的左右子节点和随机节点,并检查它们是否已被克隆。提供的代码示例展示了如何实现这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值