Leetcode:133.克隆圖
阿新 • • 發佈:2018-12-05
克隆一張無向圖,圖中的每個節點包含一個 label
(標籤)和一個 neighbors
(鄰接點)列表 。
OJ的無向圖序列化:
節點被唯一標記。
我們用 #
作為每個節點的分隔符,用 ,
作為節點標籤和鄰接點的分隔符。
例如,序列化無向圖 {0,1,2#1,2#2,2}
。
該圖總共有三個節點, 被兩個分隔符 #
分為三部分。
- 第一個節點的標籤為
0
,存在從節點0
到節點1
和節點2
- 第二個節點的標籤為
1
,存在從節點1
到節點2
的一條邊。 - 第三個節點的標籤為
2
,存在從節點2
到節點2
(本身) 的一條邊,從而形成自環。
我們將圖形視覺化如下:
1 / \ / \ 0 --- 2 / \ \_/
解題思路:
廣度優先搜尋,對映(unordered_map)。圖的克隆,也就是建立一個新的圖,使得舊圖和新圖的結構一致,每個結點存在對映關係,並且對應結點的值相等,並且鄰居的值也對應相等。
- 建立對映關係,結點與結點的對映。unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>mp;
- 設定廣度搜索需要的佇列,Q,Qc分別對應原圖佇列以及克隆圖佇列。
- 首先克隆圖的第一個結點,*clone=new UndirectedGraphNode(node->label)。建立這兩個結點的對映關係mp[node]=clone。
- 下一步將克隆node結點的鄰居。克隆鄰居時會遇到兩種情況原圖的鄰居不能對映到新圖,也就意味著,需要建立新的結點然後建立對映關係。或者能找到對映關係,說明這對結點之前訪問過。例如,上面訪問上圖的1時,鄰居0能找到對映,因為之前被訪問,而鄰居2結點不能找到對映。不論之間有沒有訪問都需要將鄰居加入
- 加入鄰居之後,如果這個結點剛剛才被建立,那麼將這對結點分別加入自己的佇列。之後將當前訪問的結點出隊。
- 直到佇列為空,說明圖克隆完畢,return clone。
class Solution { public: UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { if (node == NULL) return NULL; queue<UndirectedGraphNode*> Q,Qc; UndirectedGraphNode *clone=new UndirectedGraphNode(node->label), *temp,*tempc; unordered_map<UndirectedGraphNode*, UndirectedGraphNode*>mp;//兩個圖的對映 Q.push(node); Qc.push(clone); mp[node] = clone; UndirectedGraphNode *p; while (!Q.empty()) { temp = Q.front(); tempc = Qc.front(); int size = temp->neighbors.size(); for (int i = 1; i <= size; i++) { p = temp->neighbors[i - 1]; if (mp[p] == NULL) { UndirectedGraphNode* newC = new UndirectedGraphNode(p->label); tempc->neighbors.push_back(newC); Q.push(p); Qc.push(newC); mp[p] = newC; } else { tempc->neighbors.push_back(mp[p]); } } Q.pop(); Qc.pop(); } return clone; } }; |