首页 > 代码库 > Copy Graph(BFS)
Copy Graph(BFS)
自从中午饿得被迫起来吃完了一个午饭之后,就开始做这道题。鉴于之前做过一道Copy List with Random Pointer的题,看了大神的答案之后比自己想的快,就借鉴了那个思想,原先我的想法是用map的key记录原结点的引用,将新建结点的引用存入value,鉴于大神是将copy的结点接在原结点之后再删除,代码简洁得让我震惊啦,而且效率也比我的高,这回用的也是这个思想,就是将copy的结点插入原结点的neighbors的第一个,之后再拆掉。。。用的BFS。。。结果。。因为BFS之前完全没写过,第一次写,用了一个下午写完了(中间间歇和我家亲爱哒聊个QQ神马的降低效率的事情我才不会写粗来呢~╭(╯^╰)╮),之后调程序用了一个晚上。。。有个错误是
让我纠结了好久。。。差点就放弃想看答案了。。。后来试着把每个插入原结点的neighbors的第一个结点给删掉了就好了。。。。
还有就是怎么判断结点是否被访问过,这个也让我想了很久,出了很多错,因为《算法导论》里是有color来标记的,可是这个题目并没有这个属性,所以几乎每次遍历都是不一样的判断方法,但是总归思想就是,如果没有访问过,就要标记访问了,并且入队,之前错误在于入队了,但是没有标记访问,所以出了各种错。
写了好大一长串。。。后来看了大神答案,然后又被大神简洁的代码震惊了一次。。。好吧,一直在震惊,从未停止过。。。发现大神用的居然是用map储存key的思想。。。而且提交后还是比我的快。。。虽然只快了十几ms,但是也是快了。。。T_T。。。突然觉得。。。思想我是学会了,可是还是不会灵活运用啊。。。哎。。。不管了,明天用map的方法写个DFS的试试。。
下面上我的代码:
class Solution {public:// 三次遍历,第一次clone原结点, 第二次clone neighbors节点,第三次删除clone的结点// 1. 访问过一个结点,则在其neighbors的头插入新建的clone的结点,如果一个结点的neighbors[0]的label是自己,且地址不是自己,则表明被访问过// 2. 再遍历一遍,结点node的neighbors是原来的neighbors的第一个结点 UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if(node == NULL) return NULL; // 用BFS遍历 UndirectedGraphNode *cur = node, *nei; queue<UndirectedGraphNode *> que; vector<UndirectedGraphNode *> neighbors; UndirectedGraphNode *p = new UndirectedGraphNode(node->label); (cur->neighbors).insert(cur->neighbors.begin(), p); que.push(cur); while(!que.empty()){ // 第一遍 cur = que.front(); que.pop(); neighbors = cur->neighbors; if(neighbors.size() > 1){ for(int i = 1; i != neighbors.size(); ++ i){ // 遍历cur的相邻结点, 不包括nei[0],因为0是cur的clone nei = neighbors[i]; // 如果nei没被访问过,则clone并入队 if(nei->neighbors.empty() ||(nei->neighbors[0]->label != nei->label) || (nei->neighbors[0] == nei)){ p = new UndirectedGraphNode(nei->label); (nei->neighbors).insert(nei->neighbors.begin(), p); que.push(nei); } } } } que.push(node); // 先将node的neighbors复制给newNode的neighbors copyNeighbors(node); while(!que.empty()){// 第二遍,如果nei的neighbors.size() > 1,并且nei的neighbors[0].neighbors为空,则说明没访问过 cur = que.front(); que.pop(); neighbors = cur->neighbors; for(int i = 1; i != neighbors.size(); ++i){ // 将cur的相邻结点入队 nei = neighbors[i]; UndirectedGraphNode *newNode = nei->neighbors[0]; if(((nei->neighbors).size() > 1) && (newNode->neighbors).empty()){ // 说明没被访问过 copyNeighbors(nei); // 访问他,并将它入队 que.push(nei); } } } UndirectedGraphNode *u = node->neighbors[0]; // 第三遍,删除vector的第一项 que.push(node); node->neighbors.erase(node->neighbors.begin()); while(!que.empty()){ cur = que.front(); que.pop(); neighbors = cur->neighbors; for(int i = 0; i != neighbors.size(); ++i){ if(neighbors.empty()) break; nei = neighbors[i]; if(!nei->neighbors.empty() && (nei->label == nei->neighbors[0]->label) && (nei != nei->neighbors[0])){ nei->neighbors.erase(nei->neighbors.begin()); que.push(nei); } } } return u; } void copyNeighbors(UndirectedGraphNode *node){ UndirectedGraphNode *newNode = node->neighbors[0]; vector<UndirectedGraphNode *> neighbors = node->neighbors; for(int i = 1; i != neighbors.size(); ++ i){// 先将node的neighbors复制给newNode的neighbors (newNode->neighbors).push_back(neighbors[i]->neighbors[0]); } }};
Copy Graph(BFS)