leetcode 133. Clone Graph

这篇博客介绍了如何使用C++实现图的克隆,重点在于邻接链表的建模和BFS遍历。通过创建一个映射存储原图与克隆图节点的关系,并使用一个集合跟踪已访问节点,确保了全图的正确复制。这种方法的时间和空间复杂度都是O(V+E),其中V是节点数,E是边数。

题目概述

解题思路

这道题的主要难点在于两个:

  1. 建图
  2. 遍历

这道题依然采用了邻接链表的方式建图,之前我建图采用的方式是:开一个两个维度的数组,第一个维度表示节点的数目,第二个维度表示和每个节点相连的边:

class Edges
{
public:
    int weight;
    string val;
    Edges(int wi, string vi): weight(wi), val(vi){}
};

map<string, int> str2idx;
vector<Edges*> Node[N];

这种表示的缺点在于,每个节点的值不方便直接获取,因为它们都被存放在Edges这个类中。

Leetcode这种建图的方式在访问节点值的时候就更为方便:

class Node
{
public:
    int val;
    vector<Node *>neighbors;

    Node (int vi, vector<Node*> ni)
    {
        val = vi;
        neighbors = ni;
    };
    
};

下一步是遍历图。这里我们采用BFS进行原图遍历,只需维护一个set,用来判断之前的节点是否被访问过即可。每次访问到原图的某个节点,就生成相应的一个节点,然后在克隆图中插入。这样就完成了全图克隆。

方法性能

假设原图含V个节点和E条边,方法的时空复杂度均为O(V +E):

代码示例

class Solution {
public:
    unordered_map<Node *, Node *> old2new;
    unordered_set<Node *> old_nvis;

    Node *getCorresNode(Node *old_n)
    {
        if(old2new.find(old_n) == old2new.end())
        {
            Node *new_n = new Node(old_n->val, vector<Node*>());
            old2new[old_n] = new_n;
        }
        return old2new[old_n];
    }

    Node* cloneGraph(Node* node) 
    {
        if(node == NULL)
            return node;
        queue<Node *> cur_N;
        cur_N.push(node);
        while(!cur_N.empty())
        {
            Node *temp_n = cur_N.front();
            cur_N.pop();
            if(old_nvis.find(temp_n) == old_nvis.end())
            {
                old_nvis.insert(temp_n);
                Node *new_node = getCorresNode(temp_n);

                vector<Node *> neigh = temp_n->neighbors;
                for (vector<Node *>::iterator iter = neigh.begin(); iter != neigh.end(); ++iter)
                {
                    cur_N.push(*iter);
                    Node *tmp_neigh = getCorresNode(*iter);
                    new_node->neighbors.push_back(tmp_neigh);
                }
            }
        }

        return old2new[node];
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值