最低公共祖先问题的求解

原创 2016年08月30日 21:28:14

1.树的公共祖先问题

       首先明确一下这里的公共祖先的概念。所谓公共祖先,就是两节点位于不同分支或者同一分支,最近的公共的父节点(说父节点不太准确,可能是祖父节点等)。

       我们先不考虑算法,让我们自己找两个节点的最低公共祖先,我们应该是要按照路径找到两个节点,然后看两条路径的交点。很好,我们自下而上找交点是我们解决问题的思想。

       变形1:我们可以从根节点遍历,若左子节点为根的左子树包含两个节点,则递归至左子树;若右子节点为根的右子树包含两个节点则递归至右子树。否则直接返回根节点。

       注:此时树要是二叉搜索树,可以比较节点值的大小来进行变形1的计算。

       若此时有指向父节点的指针,则从两个节点出发,问题转化为求两个链表的交点。

       变形2:这个更加符合我们的思路,直接找到到两个节点的路径,求得路径的交点。

       变形2的参考代码如下:

#include<iostream>
#include<list>
#include<vector>
using namespace std;

struct TreeNode
{
	int value;
	vector<TreeNode *>m_vChildren;
};

bool GetNodePath(TreeNode *pRoot,TreeNode *pNode,list<TreeNode *>&path)
{
	if(pRoot==pNode)
		return true;
	path.push_back(pRoot);
	bool found=false;
	vector<TreeNode *>::iterator i=pRoot->m_vChildren.begin();
	while(!found&&i<pRoot->m_vChildren.end())
	{
		found=GetNodePath(*i,pNode,path);
		++i;
	}
	if(!found)
	{
		path.pop_back();
	}
	return found;
}

TreeNode *GetLastCommonNode(list<TreeNode *>&path1,list<TreeNode *>&path2)
{
	list<TreeNode *>::iterator i1=path1.begin();
	list<TreeNode *>::iterator i2=path2.begin();

	TreeNode *node=NULL;
	while(i1!=path1.end()&&i2!=path2.end())
	{
		if(*i1==*i2)
			node=*i1;
		i1++;
		i2++;
	}
	return node;
}

TreeNode *GetLastCommonParent(TreeNode *pRoot,TreeNode *pNode1,TreeNode *pNode2)
{
	if(pRoot==NULL||pNode1==NULL||pNode2==NULL)
		return NULL;
	list<TreeNode *>path1;
	list<TreeNode *>path2;
	GetNodePath(pRoot,pNode1,path1);
	GetNodePath(pRoot,pNode2,path2);
	return GetLastCommonNode(path1,path2);
}


       代码是以多叉树的结构来写的。

       之所以写这篇文章,是因为我们自己都会找最低公共祖先。但同时转化为程序、算法就显得有些吃力。其实这些还是人的解决方法一步步转化、提炼、优化。这个思路的过程:

       自己的解决办法---->转化为算法

       我之前有文章所说的不要自己凭空制造规则,所谓规则就是算法。我曾经为求简单,制造简单的规则是满足case较少的情况,但对于问题的解决没什么用。(自己制造的规则仅满足case1)。所以将你的解法概括为算法能够解决一类问题,每一步都很关键。但要大胆地迈出那一步,去不断总结,不断套路(动态规划),不断成长。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

洛谷3379 最近公共祖先

dfs+并查集求LCA

LCA 最近公共祖先 tarjan离线 总结 结合3个例题

在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解   LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点。也就...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

最低公共祖先问题

问题1:求平衡二叉树的最低公共祖先。 问题2:求普通二叉树的最低公共祖先。 问题3:求普通树的最低公共祖先。 代码如下:   问题1: #include using namespace ...

最低公共祖先问题的求解

1.树的公共祖先问题        首先明确一下这里的公共祖先的概念。所谓公共祖先,就是两节点位于不同分支或者同一分支,最近的公共的父节点(说父节点不太准确,可能是祖父节点等)。        我...

最低公共祖先LCA

题目ps:这道题来源是剑指offer第50题;但是变种真的好多啊,所以就记录一下;树中两个结点的最低公共祖先: 首先我们要明白这个最低公共祖先是啥?对于一个结点,它上面能到达他的都叫做祖先,他的父结点...

【树】求树中两个节点的最低公共祖先

求树中的两个节点的最低公共祖先,是一组题目,不同条件下的题目是完全不一样的。情形1、二叉搜索树分析:如果树是二叉搜索树的话,就比较容易解决。因为二叉搜索树的特性,左子树的上节点的值比根节点小,右子树上...

树中两个结点的最低公共祖先50

题目描述:输入两个树节点,找出它们的最低公共祖先。这是一棵普通树而且没有指向父节点的指针。解题思路: 使用了两个链表分别保存从根节点到输入的两个结点的路径,然后把问题转换成两个链表的最后公共节点。 首...

树中节点最低公共祖先

给定两个树节点,返回这两个节点最近的一个公共父节点。二叉搜索树struct BinaryTreeNode{ int val; BinaryTreeNode* left; Bin...

hihoCoder - 1062 - 最近公共祖先·一 (树的最近公共祖先问题!)

#1062 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个...

LCA(最近公共祖先)问题 (一)

最近共祖先 对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。 另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)