Leetcode 圖 133. 克隆圖

1、問題分析

題目鏈接: https://leetcode-cn.com/problems/clone-graph/
  本質上就是一個圖的遍歷問題,首先用一個hashmap存儲節點的值和節點本身的對應關係(根據源節點創建),然後仍然根據源節點,將之前 hashmap 中沒有賦值的neighbors給賦值。最後輸出第一個節點即可。讀者可以直接看源代碼。我基本每一個重要步驟都註釋了。

2、問題解決

  筆者以C++方式解決。

#include "iostream"

using namespace std;

#include "algorithm"
#include "vector"
#include "map"

class Node {
public:
	int val;
	vector<Node *> neighbors;

	Node() {
		val = 0;
		neighbors = vector<Node *>();
	}

	Node(int _val) {
		val = _val;
		neighbors = vector<Node *>();
	}

	Node(int _val, vector<Node *> _neighbors) {
		val = _val;
		neighbors = _neighbors;
	}
};


class Solution {
private:
	//    定義頂點數目
	static const int MAXV = 101;
	//  用於複製節點時 標記是否訪問
	bool vis[MAXV] = { false };
	//    用於給neighbors賦值時, 標記是否訪問
	bool vis1[MAXV] = { false };
	//    將節點的值和節點對應
	map<int, Node *> val_map;
public:
	Node *cloneGraph(Node *node) {
		if (node == NULL) {
			return NULL;
		}
		dfs_create_node(node);
		dfs(node);
		return val_map[1];
	}

	/**
	* 根據 node 創建節點,並對應到map中
	* 本質就是圖的遍歷
	* @param node
	*/
	void dfs_create_node(Node *node) {
		//        標記該節點已經訪問
		vis[node->val] = true;
		//        根據源節點生成新節點(先賦值,不更新 neighbors ,
		//        即 neighbors 暫時爲空,因爲此時的 neighbors 節點可能還沒有new 出來)
		val_map[node->val] = new Node(node->val);
		//        根據鄰接表對圖進行深搜
		for (int i = 0; i < node->neighbors.size(); ++i) {
			//            獲取下一個訪問節點的值
			int v = node->neighbors[i]->val;
			//            如果之前沒有訪問過該節點
			if (!vis[v]) {
				//                根據 node->neighbors[i]) 創建節點,並對應到map中
				dfs_create_node(node->neighbors[i]);
			}
		}
	}

	/**
	* 根據源節點 給 map 中的 neighbors 賦值
	* @param node
	*/
	void dfs(Node *node) {
		//標記該節點已經訪問
		vis1[node->val] = true;

		//        取出map 中的節點,根據 源節點 node 的值標記 該節點的鄰接表 即 neighbors ,
		//        注意這裏的 neighbors 存儲的仍然是 map 中的節點
		for (int i = 0; i < node->neighbors.size(); ++i) {
			val_map[node->val]->neighbors.push_back(val_map[node->neighbors[i]->val]);
		}


		//        和上面一樣深搜
		for (int i = 0; i < node->neighbors.size(); ++i) {
			int v = node->neighbors[i]->val;
			if (!vis1[v]) {
				dfs(node->neighbors[i]);
			}
		}
	}
};


int main() {
	//    創建節點
	Node *pNode1 = new Node(1);
	Node *pNode2 = new Node(2);
	Node *pNode3 = new Node(3);
	Node *pNode4 = new Node(4);

	//    給節點建立鄰接表
	pNode1->neighbors.push_back(pNode2);
	pNode1->neighbors.push_back(pNode4);

	pNode2->neighbors.push_back(pNode1);
	pNode2->neighbors.push_back(pNode3);

	pNode3->neighbors.push_back(pNode2);
	pNode3->neighbors.push_back(pNode4);

	pNode4->neighbors.push_back(pNode1);
	pNode4->neighbors.push_back(pNode3);

	Solution *pSolution = new Solution;
	Node *pNode = pSolution->cloneGraph(pNode1);
	cout << pNode1 << endl;

	system("pause");
	return 0;
}

運行結果

在這裏插入圖片描述

有點菜,有時間再優化一下。

3、總結

  書上的代碼直接運行絕大部分是對的,但是總有一些軟件的更新使得作者無能爲力。之前的API是對的,但是之後就廢棄了或修改了是常有的事。所以我們需要跟蹤源代碼。這只是一個小小的問題,如果沒有前輩的無私奉獻,很難想象我們自己一天能學到多少內容。感謝各位前輩的辛勤付出,讓我們少走了很多的彎路!

點個贊再走唄!歡迎留言哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章