zoukankan      html  css  js  c++  java
  • 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]);
                }
        }
    };
  • 相关阅读:
    Mysql操作命令(基础)
    jmeter—建立测试计划
    iperf—流量测试
    BatchConfigTool批量配置工具
    Ipinstall软件工具-可视对讲
    General VDPConfig对讲配置工具
    Mobaxterm使用(类似xshell)
    Putty——支持Telnet,ssh连接的连接软件
    海康—SADP激活(设备网络搜索)
    FinalShell—一体化服务器管理软件(SSH客户端)
  • 原文地址:https://www.cnblogs.com/skysand/p/4036218.html
Copyright © 2011-2022 走看看