• LeetCode Clone Graph


    class Solution {
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
            UndirectedGraphNode *clone = dfs(node);
            dfs_clear(node);
            return clone;
        }
        
        UndirectedGraphNode *dfs(UndirectedGraphNode *orgin) {
            if (orgin == NULL) return NULL;
            UndirectedGraphNode *clone = get_clone_node(orgin);
            if (clone != NULL) return clone;
            // cout<<"cloning node :"<<orgin->label<<endl;
            int olen = orgin->neighbors.size();
            
            clone = add_clone_node(orgin);
            
            for (int i=0; i<olen; i++) {
                UndirectedGraphNode *nb = orgin->neighbors[i];
                clone->neighbors.push_back(dfs(nb));
            }
            return clone;
        }
        
        void dfs_clear(UndirectedGraphNode *node) {
            UndirectedGraphNode *clone = get_clone_node(node);
            if (clone == NULL) return;
            // cout<<"clear node: "<<node->label<<endl;
            del_clone_node(node);
            
            int len = node->neighbors.size();
            
            for (int i=0; i<len; i++) {
                dfs_clear(node->neighbors[i]);
            }
        }
        
        UndirectedGraphNode *get_clone_node(UndirectedGraphNode *node) {
            int len;
            // cout<<"get info of cloned node : "<<node->label<<endl;
            if (node == NULL || (len = node->neighbors.size()) < 2
                || node->neighbors[len - 2] != NULL) return NULL;
            return node->neighbors[len - 1];
        }
        
        UndirectedGraphNode *add_clone_node(UndirectedGraphNode *node) {
            if (node == NULL) return NULL;
            // cout<<"append link for cloned node: "<<node->label<<endl;
            node->neighbors.push_back(NULL);
            node->neighbors.push_back(new UndirectedGraphNode(node->label));
            return node->neighbors.back();
        }
        
        void del_clone_node(UndirectedGraphNode *node) {
            if (get_clone_node(node) == NULL) return;
            // cout<<"del clone link for node:"<<node->label<<endl;
            node->neighbors.pop_back(); // cloned node addr
            node->neighbors.pop_back(); // null
        }
    };

    dfs扫描复制,通过在neighbor数组中加入NULL指针来标记已复制与未复制的节点,同时在NULL项后存储该节点对应的克隆节点,最后将原有节点还原。240ms

    类似的可以用一个hash表来存储新节点地址与对应老节点的对应关系,同时进行连接关系的复制。当然两种方法的dfs可以改成bfs,防止栈溢出。

    class Solution {
    private:
        unordered_map<UndirectedGraphNode*, UndirectedGraphNode*> o2n;
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
            o2n.clear();
            UndirectedGraphNode *clone = dfs(node);
            return clone;
        }
        
        UndirectedGraphNode *dfs(UndirectedGraphNode *node) {
            if (node == NULL) return NULL;
            unordered_map<UndirectedGraphNode *, UndirectedGraphNode *>::iterator iter = o2n.find(node);
            if (iter != o2n.end()) return iter->second;
            
            UndirectedGraphNode *clone = new UndirectedGraphNode(node->label);
            o2n.insert(make_pair(node, clone));
            
            int len = node->neighbors.size();
            
            for (int i=0; i<len; i++) {
                clone->neighbors.push_back(dfs(node->neighbors[i]));
            }
            return clone;
        }
    };

    第二轮:

    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 #.

    1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
    2. Second node is labeled as 1. Connect node 1 to node 2.
    3. 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
             / 
             \_/

    故技重施:

    /**
     * Definition for undirected graph.
     * struct UndirectedGraphNode {
     *     int label;
     *     vector<UndirectedGraphNode *> neighbors;
     *     UndirectedGraphNode(int x) : label(x) {};
     * };
     */
     // 9:20
    class Solution {
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
            if (node == NULL) {
                return NULL;
            }
            duplicate(node);
            clone(node);
            UndirectedGraphNode* res = node->neighbors.back();
            restore(node);
            return res;
        }
        
        void duplicate(UndirectedGraphNode *node) {
            if (node == NULL) {
                return;
            }
            int nlen = node->neighbors.size();
            if (nlen > 1 
                && node->neighbors[nlen - 2] == NULL
                && node->neighbors[nlen - 1]->label == node->label) {
                // we have duplicated it
                return;
            }
            // we haven't duplicated this node
            node->neighbors.push_back(NULL);
            UndirectedGraphNode* tmp = new UndirectedGraphNode(node->label);
            node->neighbors.push_back(tmp);
            
            for (int i=0; i<nlen; i++) {
                tmp->neighbors.push_back(node->neighbors[i]);
            }
            
            for (int i=0; i<nlen; i++) {
                duplicate(node->neighbors[i]);
            }
        }
        
        void clone(UndirectedGraphNode *node) {
            if (node == NULL) return;
            int nlen = node->neighbors.size();
            UndirectedGraphNode *newNode = node->neighbors.back();
            if (nlen <= 2 || node->neighbors[0] != newNode->neighbors[0]) {
                // already cloned it
                return;
            }
            
            for (int i=0; i<nlen-2; i++) {
                   newNode->neighbors[i] = newNode->neighbors[i]->neighbors.back();
            }
            
            for (int i=0; i<nlen-2; i++) {
                clone(node->neighbors[i]);
            }
        }
        
        void restore(UndirectedGraphNode *node) {
            if (node == NULL) {
                return;
            }
            int nlen = node->neighbors.size();
            if (nlen < 2 || node->neighbors[nlen-2] != NULL) {
                return;
            }
            node->neighbors.pop_back();
            node->neighbors.pop_back();
            nlen-=2;
            for (int i=0; i<nlen; i++) {
                restore(node->neighbors[i]);
            }
        }
    };
    /**
     * Definition for undirected graph.
     * struct UndirectedGraphNode {
     *     int label;
     *     vector<UndirectedGraphNode *> neighbors;
     *     UndirectedGraphNode(int x) : label(x) {};
     * };
     */
     // 10:15
    class Solution {
    private:
        unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> addr;
    public:
        UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
            if (node == NULL) {
                return NULL;
            }
            addr.clear();
            return dfs(node);
        }
        
        UndirectedGraphNode * dfs(UndirectedGraphNode *node) {
            if (node == NULL) return NULL;
            if (addr.count(node) > 0) {
                return addr[node];
            }
            UndirectedGraphNode* tmp = new UndirectedGraphNode(node->label);
            addr[node] = tmp;
            
            int len = node->neighbors.size();
            for (int i=0; i<len; i++) {
                tmp->neighbors.push_back(node->neighbors[i]);
            }
            for (int i=0; i<len; i++) {
                tmp->neighbors[i] = dfs(tmp->neighbors[i]);
            }
            return tmp;
        }
    };
  • 相关阅读:
    man LVCREATE
    Pyhton---基础---递归
    Python---基础---循环,函数
    Python---基础---dict_tuple_set
    Python---基础---dict和set2
    安卓网络编程学习(1)——java原生网络编程(1)
    使用python爬取B站弹幕和三连
    maven项目整合工具学习
    读阿里巴巴泰山版《java开发手册》总结(2)
    第十三周学习进度
  • 原文地址:https://www.cnblogs.com/lailailai/p/3861309.html
Copyright © 2020-2023  润新知