LeetCode【clone-graph】

思路:(无向图的复制)
题目要求的是让我们实现一个图的深拷贝。深拷贝指的是复制另外一个对象到自己的对象中,且两者不共享一个内存区,浅拷贝是指两者共享一个内存区
所以我们需要new 来开辟新的内存区执行拷贝。还要注意一个问题。我们这个图实际上是个有向图,如果A有一个相邻顶点B,则A->B, 但是B能否到A取决
于B是否有相邻顶点A. 也就是说如果B能达到A,说明图中存在环,如果不考虑环的存在,我们在拷贝中可能形成死循环。

假设我们从图的A点出发,进行拷贝得到A(A2), 发现A有一个相邻顶点B,然后进行拷贝得到B(B2),然后链接A2->B2,使得B2成为A2的相邻顶点。接着,我
们操作B, 发现B有一个相邻顶点A, 而A我们是已经进行过拷贝的了。如果我们又对A再次进行拷贝, 将形成个死循环,我们要做的仅是将B2->A2连接起来。
如何才能避免这种再次拷贝呢?我们只需要一个map即可,每次我们做一份拷贝,就放入map中,下次查询,如果是已经有的copy就不再继续拷贝,只是连接。
如果没有,就做拷贝,然后连接,然后放入map. map的key是原来的顶点,value是原来定点的copy版。

注:深拷贝是指源对象与拷贝对象相互独立,其中任何一个对象的改动都不会对另一个对象造成影响

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        /*BFS 复杂度:O(N),因为我们把每个结点都访问一遍,空间复杂度是栈或者队列加上map的大小,不会超过O(N)。*/
        if (node == NULL)
            return NULL;
        
        //开辟新的空间存储copy
        UndirectedGraphNode *copy = new UndirectedGraphNode(node->label);
        //查找去重用的map unordered_map<node, clonedNode> 放原始node和其复制品
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> cmap;
        //存储的队列,进行BFS
        queue<UndirectedGraphNode*> graphQ;
        graphQ.push(node);                      //根节点入队列
        cmap.insert({node, copy});                          //把根节点和其复制品放入map
        
        while (!graphQ.empty())
        {
            UndirectedGraphNode *cur = graphQ.front();      //处理当前对象
            graphQ.pop();
            UndirectedGraphNode *curClone = cmap[cur];      //处理对象的复制品,因为前面的neighbor里已经被创建
            
            //对当前顶点的每一个neighbor进行判断,因为有的neighbor已经被复制,有的没有
            for (int i = 0; i < cur->neighbors.size(); i++)
            {
                UndirectedGraphNode *neighbor = cur->neighbors[i];
                //如果之前没有拷贝过
                if (cmap.find(neighbor) == cmap.end())
                {
                    UndirectedGraphNode *neighborClone = new UndirectedGraphNode(neighbor->label);
                    curClone->neighbors.push_back(neighborClone);        //给curClone添加复制的neighbor
                    cmap.insert({neighbor, neighborClone});             //添加到map中
                    graphQ.push(neighbor);                              //添加到队列为了将来的遍历
                }
                else        //之前已经复制过的neighbor
                {
                    UndirectedGraphNode *neighborClone = cmap[neighbor];    //从map中取出之前的copy版本
                    curClone->neighbors.push_back(neighborClone);       //给curClone添加复制的neighbor
                }
            }
        }
        return copy;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值