LeetCode 克隆圖

hestyle發表於2019-02-22

克隆一張無向圖,圖中的每個節點包含一個 label (標籤)和一個 neighbors (鄰接點)列表 。
OJ的無向圖序列化:
節點被唯一標記。
我們用 # 作為每個節點的分隔符,用 , 作為節點標籤和鄰接點的分隔符。

例如,序列化無向圖 {0,1,2#1,2#2,2}。
該圖總共有三個節點, 被兩個分隔符  # 分為三部分。 
第一個節點的標籤為 0,存在從節點 0 到節點 1 和節點 2 的兩條邊。
第二個節點的標籤為 1,存在從節點 1 到節點 2 的一條邊。
第三個節點的標籤為 2,存在從節點 2 到節點 2 (本身) 的一條邊,從而形成自環。

我們將圖形視覺化如下:
       1
      / \
     /   \
    0 --- 2
         / \
         \_/

思路分析:首先採取廣度優先遍歷,將所有的圖中所有的節點進行訪問,並且得到所有的節點地址。然後新建節點,並且將原來的節點與這些新建的節點一一對應的關聯,並且複製這些節點的 label (標籤),最後複製這些節點的neighbors (鄰接點)。

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
	vector<UndirectedGraphNode*> undifGNVec;//圖的節點遍歷序列
	map< UndirectedGraphNode*, UndirectedGraphNode*> hashMap;
	UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
		if (node == NULL) {
			return NULL;
		}
		undifGNVec.push_back(node);//起始節點,放入遍歷序列
		UndirectedGraphNode *nodePtr;
		queue<UndirectedGraphNode*> myQueue;//廣度優先遍歷的輔助佇列
		myQueue.push(node);
		//利用輔助佇列,廣度優先遍歷圖
		while (!myQueue.empty()) {
			int tempSize = myQueue.size();//上一次佇列的大小
			//將上一次佇列清空,並且放入新的未位訪問的節點
			for (int i = 0; i < tempSize; ++i) {
				nodePtr = myQueue.front();
				myQueue.pop();
				for (auto vecIt : nodePtr->neighbors) {
					//如果這個點沒有訪問過
					if (find(undifGNVec.begin(), undifGNVec.end(), vecIt) == undifGNVec.end()) {
						undifGNVec.push_back(vecIt);//放到遍歷序列
						myQueue.push(vecIt);//放到隊尾
					}
				}
			}
		}
		//將undifGNVec中的所有節點label複製,並且有map容器將它們進行關聯
		for (auto it : undifGNVec) {
			nodePtr = new UndirectedGraphNode(it->label);
			hashMap[it] = nodePtr;
		}
		//將undifGNVec中的所有節點neighbors複製
		for (auto it : undifGNVec) {
			for (auto vecIt : it->neighbors) {
				hashMap[it]->neighbors.push_back(hashMap[vecIt]);
			}
		}
		nodePtr = hashMap[node];
		return nodePtr;
	}
};

在這裡插入圖片描述
遞迴演算法實現

/**
 * Definition for undirected graph.
 * struct UndirectedGraphNode {
 *     int label;
 *     vector<UndirectedGraphNode *> neighbors;
 *     UndirectedGraphNode(int x) : label(x) {};
 * };
 */
class Solution {
public:
    UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
        if (!node) return NULL;
        //複製節點label (標籤
        UndirectedGraphNode *rtn = new UndirectedGraphNode(node->label);
        //進行map標記
        my_map.insert(make_pair(node, rtn));
        //訪問它的neighbors (鄰接點)
        for (int i = 0; i < (node->neighbors).size(); i++) {
            //如果已經訪問過
            if (my_map.find(node->neighbors[i]) != my_map.end()) {
                rtn->neighbors.push_back(my_map[node->neighbors[i]]);
            } else {
                UndirectedGraphNode *data = cloneGraph(node->neighbors[i]);
                rtn->neighbors.push_back(data);
            }
        }
        return rtn;
    }
private:
    map<UndirectedGraphNode *, UndirectedGraphNode *> my_map;
};

相關文章