【leetcode】Clone Graph

问题

给定一个无向图,对该无向图进行拷贝,图中每个结点包含一个label 域和一个用来记录相临节点的vector容器。假设label是唯一的

分析

在这之前,我们回忆图的遍历算法,宽度优先(BFS)或深度优先(DFS)。这里我们以深度优先为例来进行分析,首先看代码。
//dfs visit graph
typedef UndirectedGraphNode ufn;
typedef hash_map<ufn*, ufn*> copyedMap;

void dfs(ufn *node, hash_set<ufn *>& visited)
{
	if(node == NULL)
		return;
	if(visited.find(node) == visited.end())
	{
		cout << node->label << "  ";
		visited.insert(node);
	}
	for (int i = 0; i < node->neighbors.size(); ++i)
	{
		dfs(node->neighbors[i], visited);
	}
}

void visitGraph( ufn *first)
{
	if(first == NULL)
		return;
	hash_set<ufn* > visited;
	visited.clear();
	dfs(first,visited);
	return;
}

dfs 和 bfs访问图以及树结构是基本的也是必须掌握的,这里不展开赘述。
仔细体会下这个dfs访问结点的函数,我们是不是得到什么启示呢?在copy 节点的时候,是不是也恰恰就是visit 模式?

实现:

ufn* dfs(UndirectedGraphNode* node,copyedMap& copyedNodes){
	if(node == NULL)
		return NULL;
	if(copyedNodes.find(node) != copyedNodes.end())
		return copyedNodes[node];
	else 
		{
			ufn *copyed = new ufn(node->label);
			copyedNodes[node] = copyed; 
			for (int i = 0; i < node->neighbors.size(); ++i)
			{
				copyed->neighbors.push_back(dfs(node->neighbors[i],copyedNodes));
			}
			return copyed;
	    }
}

 UndirectedGraphNode* cloneGraph(UndirectedGraphNode *node){
	 hash_map<UndirectedGraphNode*, UndirectedGraphNode*> copyedNodes;
	 return dfs(node, copyedNodes);
 }

代码是不是属于同一种模式?

总结:

对于树的三种访问形式(前,中,后序),一定要熟记于胸,这里不是指代码,而是思想,直白点就是模式,很多复杂的,看似生疏的问题,都是从这里衍生出来的,只不过不再是简单的print,而是要做些其他的额外工作而已。以及这里提到的DFS,BFS。同理,对于图也是如此,当然图而言就是DFS,BFS。

ufn * createGraph(const string &graph){
	if(graph.size() == 0)
		return NULL;
	int i = 0;
	//assume the label is different.
	hash_map<char, ufn*> createdNodes;
	createdNodes.clear();

	while (i < graph.size())
	{
		ufn* node;
		if(createdNodes.find(graph[i]) != createdNodes.end())
			node = createdNodes[graph[i]];
		else
		    {
				node = new ufn(graph[i] - '0');
				createdNodes[graph[i]] = node;
		}
		++i;
		while (i < graph.size() && graph[i] != '#')
		{
			if(graph[i] != ',')
			{
				if(createdNodes.find(graph[i]) != createdNodes.end())
					node->neighbors.push_back(createdNodes[graph[i]]);
				else
				{
					createdNodes[graph[i]] =  new ufn(graph[i] - '0');
					node->neighbors.push_back(createdNodes[graph[i]]);
				}
			}
			++i;
		}
		++i;//skip the '#'
	}
	return createdNodes[graph[0]];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值