LintCode-137: Clone Graph (BFS经典题)

思路就是用一个hashmap维护原图和克隆图之间的节点关系。用BFS从原图的给入节点node展开,每次检查其neighbor节点,若已经在hashmap中,则不需要克隆新节点和新边,只需将这个neighbor节点入queue即可。若该neighbor节点不在hashmap中,则克隆新节点和新边,当然这个旧neighbor节点还是要入queue。

代码如下:

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */


class Solution {
public:
    /*
     * @param node: A undirected graph node
     * @return: A undirected graph node
     */
    UndirectedGraphNode* cloneGraph(UndirectedGraphNode* node) {
        if (!node)
            return NULL;
        
        UndirectedGraphNode * p1 = node;
        UndirectedGraphNode *p2 = new UndirectedGraphNode(node->label);
        //hashmap stores the mirror copy relationship between the original graph and the cloned graph.
        map<UndirectedGraphNode *, UndirectedGraphNode *> hashmap; 
        hashmap[p1]=p2;
        queue<UndirectedGraphNode *> q;
        q.push(p1);
        
        while(!q.empty()) {
            p1=q.front();
            q.pop();
            p2=hashmap[p1];
            
            for (int i=0; i<p1->neighbors.size(); ++i) {
                UndirectedGraphNode * pNode=p1->neighbors[i];
                if (hashmap.count(pNode)>0) {   //important here!!!
                    // If pNode is already in hashmap, then its counterpart in the clone graph already exists. We just 
                    // need to add the edge. 
                    p2->neighbors.push_back(hashmap[pNode]); //do not push_back(pNode) as pNode is from the old graph.
                    //do not push pNode into q here as it has been queued before!
                    
                } else {
                    // If pNode is not in hashmap, it shows its counterpart in the clone graph does not exist. We need
                    // to create the node first, then add the edge.
                    UndirectedGraphNode* tempNode = new UndirectedGraphNode(pNode->label);
                    hashmap[pNode]=tempNode; //stores the mirror relationship between pNode and tempNode;
                    p2->neighbors.push_back(tempNode); //here we can push_back(tempNode) as it is from the cloned graph.
                    q.push(pNode); //push pNode into queue.
                }
            }
        }
        
        return hashmap[node];
    }
};

二刷:

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    /**
     * @param node: A undirected graph node
     * @return: A undirected graph node
     */
    UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
        if (node == nullptr) return nullptr;
        map<UndirectedGraphNode *, UndirectedGraphNode*> mp;
        queue<UndirectedGraphNode *> q;
        q.push(node);
        mp[node] = new UndirectedGraphNode(node->label);
        while(!q.empty()) {
            UndirectedGraphNode * frontNode = q.front();
            q.pop();
            for (auto neighbor : frontNode->neighbors) {
                if (mp.find(neighbor) == mp.end()) {
                    mp[neighbor] = new UndirectedGraphNode(neighbor->label);
                    //mp[frontNode]->neighbors.push_back(mp[neighbor]);
                    q.push(neighbor);
                }
                mp[frontNode]->neighbors.push_back(mp[neighbor]); //注意,不管frontNode是否在map中出现过,都要复制它的neighbor关系。
            }
        }
        return mp[node];
    }
};

三刷:

class Solution {
public:
    /**
     * @param node: A undirected graph node
     * @return: A undirected graph node
     */
    UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
        if (!node) return NULL;
        queue<UndirectedGraphNode *> q;
        q.push(node);
        orig2New[node] = new UndirectedGraphNode(node->label);
        while (!q.empty()) {
            UndirectedGraphNode *frontNode = q.front();
            q.pop();
            for (auto neighbor : frontNode->neighbors) {
                if (orig2New.find(neighbor) == orig2New.end()) {
                    UndirectedGraphNode* newNeighbor = new UndirectedGraphNode(neighbor->label);
                    orig2New[neighbor] = newNeighbor;
                    q.push(neighbor);  //注意q.push() 要放到if()里面,也就是这个neighbor之前没有被处理过。
                }
                orig2New[frontNode]->neighbors.push_back(orig2New[neighbor]);
            }
        }
        return orig2New[node];
    }
private:
    map<UndirectedGraphNode *, UndirectedGraphNode *> orig2New;
};

解法2:DFS

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    /**
     * @param node: A undirected graph node
     * @return: A undirected graph node
     */
    UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
        if (node == nullptr) return nullptr;
        if (mp.find(node) != mp.end()) return mp[node];
        mp[node] = new UndirectedGraphNode(node->label);

        for (auto neighbor : node->neighbors) {
            mp[node]->neighbors.push_back(cloneGraph(neighbor));
        }
        return mp[node];
    }
private:
    map<UndirectedGraphNode *, UndirectedGraphNode*> mp;
};

二刷:

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */

class Solution {
public:
    /**
     * @param node: A undirected graph node
     * @return: A undirected graph node
     */
    UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node) {
        if (!node) return NULL;
        if (orig2New.find(node) == orig2New.end()) {
            UndirectedGraphNode *newNode = new UndirectedGraphNode(node->label);
            orig2New[node] = newNode;
        }
        for (auto pNeighbor : node->neighbors) {
            if (orig2New.find(pNeighbor) == orig2New.end()) {
                UndirectedGraphNode *pNewNeighbor = cloneGraph(pNeighbor);
                orig2New[pNeighbor] = pNewNeighbor;
            }
            orig2New[node]->neighbors.push_back(orig2New[pNeighbor]);
        }
        return orig2New[node];
    }
private:
    map<UndirectedGraphNode *, UndirectedGraphNode *> orig2New;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值