Leetcode-Graph-Hash

133. Clone Graph

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ’s undirected graph serialization:
Nodes are labeled uniquely.

We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.
As an example, consider the serialized graph {0,1,2#1,2#2,2}.

The graph has a total of three nodes, and therefore contains three parts as separated by #.

First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
Second node is labeled as 1. Connect node 1 to node 2.
Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.
Visually, the graph looks like the following:

   1
  / \
 /   \
0 --- 2
     / \
     \_/
#include <string>
#include <iomanip>
#include <utility> 
#include <memory>
#include <iostream>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>

using namespace std;

struct UndirectedGraphNode {
     int label;
     vector<UndirectedGraphNode *> neighbors;
     UndirectedGraphNode(int x) : label(x) {};
 };
typedef UndirectedGraphNode undgp;
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if (!node)return node;
        mmap.clear();
        mset.clear();
        innerv.clear();
        innerv.reserve(1000000);
        cloneGraph1(node);
        if(mset.empty()){
            decltype(node) res;
            res = new UndirectedGraphNode(node->label);
            return res;
        }
        unordered_map<undgp*, undgp*> mp1;
        for (auto it : mset) {
            mp1[it] = new undgp(it->label);
        }
        for (auto it : mset) {
            auto dp = mp1[it];
            for (auto it_ : it->neighbors) {
                dp->neighbors.push_back(mp1[it_]);
            }
        }
        return mp1[node];
    }
    void cloneGraph1(UndirectedGraphNode *node) {
        if (!node || node->neighbors.empty())return;
        auto resf = mmap.find(node);
        mset.insert(node);
        for (auto it : node->neighbors) {
            resf = mmap.find(node);
            mset.insert(it);
            if (resf == mmap.end()) {
                unordered_set<undgp*> tmps;
                tmps.insert(it);
                innerv.push_back(tmps);
                mmap.insert(pair<undgp*,miter>(node, innerv.end()-1));
                auto resf2 = mmap.find(it);
                if (resf2 == mmap.end()) {
                    unordered_set<undgp*> tmps2;
                    tmps2.insert(node);
                    innerv.push_back(tmps2);
                    mmap.insert(pair<undgp*,miter>(it, innerv.end()-1));
                } else {
                    resf2->second->insert(node);
                }
                cloneGraph1(it);
            } else {
                auto resf1 = mmap[node]->find(it);
                if (resf1 == mmap[node]->end()) {
                    mmap[node]->insert(it);
                    auto resf2 = mmap.find(it);
                    if (resf2 == mmap.end()) {
                        unordered_set<undgp*> tmps2;
                        tmps2.insert(node);
                        innerv.push_back(tmps2);
                        mmap.insert(pair<undgp*,miter>(it, innerv.end()-1));
                    } else {
                        resf2->second->insert(node);
                    }
                    cloneGraph1(it);
                }
            }
        }// it
    }
    vector<unordered_set<undgp*>> innerv;
    typedef vector<unordered_set<undgp*>>::iterator miter;
    unordered_map<undgp*,decltype(innerv)::iterator> mmap;
    unordered_set<undgp*> mset;
};

int main() {

    Solution s;
    UndirectedGraphNode *d = new UndirectedGraphNode(12);
    auto d1 =  s.cloneGraph(d);
    cout << d1->label << endl;
    delete d1;
    delete d;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值