最低公共祖先问题的求解

原创 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)。所以将你的解法概括为算法能够解决一类问题,每一步都很关键。但要大胆地迈出那一步,去不断总结,不断套路(动态规划),不断成长。

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

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

树是二叉查找树的情况题目来自LeetCode:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/...
  • zhouyelihua
  • zhouyelihua
  • 2015年07月13日 11:05
  • 2643

《剑指offer》树中两个结点的最低公共祖先

说实话,和这题很有缘分。首先,这个题目给我印象很深,其次,今天在做蘑菇街实习生笔试时遇到了这个题目,所以感觉应该写博客,把这个题目记录下来。笔试时遇到的题目是:给定二叉树中的两个结点,寻找最低公共节点...
  • u010357247
  • u010357247
  • 2015年04月11日 00:27
  • 501

树---求二叉搜索树中两节点的最低公共祖先(LCA)

一、问题描述给定二叉搜索树(BST)中两节点,找出他们的最低公共祖先。例如对于下图: LCA(4, 14)=8; LCA(8, 10)=8.二、问题求解利用BST的性质,从根节点从上自下递归遍历BS...
  • will130
  • will130
  • 2015年11月02日 20:44
  • 631

二叉树中查找两个节点的最低公共祖先

这是一道企业面试中,经常会被问到的面试题目。 在网上看到一些此题的实现,其中有两种方法是比较适合编程的。本项目的源代码,请点击这里下载。 方法一:   此方法是根据二叉树的DFS查找并标记祖先,...
  • fy2462
  • fy2462
  • 2014年06月17日 14:24
  • 2251

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

情形1:树是搜索二叉树 思路:从树的根节点开始遍历,如果根节点的值大于其中一个节点,小于另外一个节点,则根节点就是最低公共祖先。否则如果根节点的值小于两个节点的值,则递归求根节点的右子树,如果大...
  • jingshuigg
  • jingshuigg
  • 2014年06月15日 22:31
  • 2262

剑指offer 面试题50—树中两个节点的最低公共祖先

#include #include #include using namespace std; typedef struct TreeNode { int data; ...
  • wtyvhreal
  • wtyvhreal
  • 2015年05月07日 19:23
  • 1885

求两个树结点的最低公共祖先(Again)

题目:输入两个树结点,求它们的最低公共祖先。 事实上,这是一组题目, 情况一:此树为二叉树,且为二叉搜索树; 二叉搜索树是排过序的,位于左子树的结点都比父节点小;位于右子树的结点都比右子树大,我们只需...
  • moli152_
  • moli152_
  • 2015年09月29日 17:43
  • 655

二叉树系列——两个节点的最低公共祖先

出处:https://segmentfault.com/a/1190000003509399 二叉搜索树: Given a binary search tree (BST), find the ...
  • liuyi1207164339
  • liuyi1207164339
  • 2016年03月17日 14:31
  • 1237

最近公共祖先(LCA)详解

LCA问题(Least Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找...
  • u014679804
  • u014679804
  • 2015年08月26日 11:09
  • 1799

最低公共祖先LCA

题目ps:这道题来源是剑指offer第50题;但是变种真的好多啊,所以就记录一下;树中两个结点的最低公共祖先: 首先我们要明白这个最低公共祖先是啥?对于一个结点,它上面能到达他的都叫做祖先,他的父结点...
  • qq_23974175
  • qq_23974175
  • 2017年05月15日 17:59
  • 159
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最低公共祖先问题的求解
举报原因:
原因补充:

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