首页 > 代码库 > Copy Graph(BFS)

Copy Graph(BFS)

    自从中午饿得被迫起来吃完了一个午饭之后,就开始做这道题。鉴于之前做过一道Copy List with Random Pointer的题,看了大神的答案之后比自己想的快,就借鉴了那个思想,原先我的想法是用map的key记录原结点的引用,将新建结点的引用存入value,鉴于大神是将copy的结点接在原结点之后再删除,代码简洁得让我震惊啦,而且效率也比我的高,这回用的也是这个思想,就是将copy的结点插入原结点的neighbors的第一个,之后再拆掉。。。用的BFS。。。结果。。因为BFS之前完全没写过,第一次写,用了一个下午写完了(中间间歇和我家亲爱哒聊个QQ神马的降低效率的事情我才不会写粗来呢~╭(╯^╰)╮),之后调程序用了一个晚上。。。有个错误是

GZRS9(3@HJS`39IU%GN~%6N

让我纠结了好久。。。差点就放弃想看答案了。。。后来试着把每个插入原结点的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)