惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
小众软件
小众软件
美团技术团队
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
D
Docker
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
B
Blog
雷峰网
雷峰网
The Cloudflare Blog

博客园 - 来自海边的一片云

Binary Tree Maximum Path Sum 解题注意 CodingTMD’s Reading List De Bruijn 序列生成 Word Ladder I ,II 解题思路 suduko及8皇后问题及相关问题的解题思路 leetcode Word Break II 解题思路 Search for a string in an infinite stream of input string. 内存管理 Permutations leetcode 开弓没有回头箭 combination sum leetcode Combinations leetcode 组合问题 word break leetcode LRU cache Leetcode 重新试着写blog SQL injection Fuzz testing XML库的解析效率 Init()
Clone Graph leetcode
来自海边的一片云 · 2014-02-10 · via 博客园 - 来自海边的一片云

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

/**

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

图的遍历有两种方法,一种是广度优先搜索,一种是深度优先搜索。

最naive的方法就是遍历一边,然后得到结果。

但是有一个需要考虑的点是,如果出现了重复怎么办

          B

        /     \

     /           \

A------------D

解决办法是,可以建一个 map 来存储已经遍历过的节点, map的pair的内容是 <oldnode, new node>

然后思路是,

1. BSF 遍历图

2. 如果节点的邻接节点没有在已经遍历过的map中出现,那么新建一个节点,更新map。

如果这个节点已经在遍历的map中出现过,那么就需要更新邻接关系即可。

    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        // BSF
        if(node == NULL) return NULL;
        queue<UndirectedGraphNode*> mq;
        unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> mp;
        UndirectedGraphNode * newnode;
        mq.push(node);
        newnode = new UndirectedGraphNode(node->label);
        mp[node] = newnode;
        
        while(!mq.empty())
        {
            UndirectedGraphNode * tmp = mq.front();
            mq.pop();            
            for(int i=0; i<tmp->neighbors.size(); i++)
            {
                UndirectedGraphNode*  neighbor = tmp->neighbors[i];                
                if(mp.find(neighbor)== mp.end())
                {
                    newnode = new UndirectedGraphNode(neighbor->label); //新建一个节点
                    mp[neighbor]= newnode;  //把这个节点加到map中去
                    mp[tmp]->neighbors.push_back(newnode);   //更新拷贝后的节点的邻接关系。
                    mq.push(neighbor); // DSF 的入queue
                }
                else
                {
                    mp[tmp]->neighbors.push_back(mp[neighbor]); //因为已经遍历过了,那就只需要更新邻接关系即可
                    
                }
            }
            
        }
        
        return mp[node];
        
    }

这个题目的思路还可以用在这道题目上

Copy List with Random Pointer

 A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        
        RandomListNode * result;
        unordered_map<RandomListNode*, RandomListNode*> mp;
        RandomListNode* node = head;
        if(head == NULL) return head;
        
        while(node!= NULL)
        {
            RandomListNode* tmpnode = new RandomListNode(node->label);
            mp[node] = tmpnode; //
            node= node->next;// go to next node
        }
        node = head;
        while(node!=NULL)
        {
            RandomListNode *randnode = node->random;
            RandomListNode *next = node->next;
            mp[node]->random = mp[randnode];
            mp[node]->next = mp[next];
            node= node->next;
        }
        
        return mp[head];
    }

对于所有有不确定的重复的情况,都可以使用类似的map来解决。