您的位置:首页 > 其它

二叉树:找出2个节点的最近公共祖先(优化算法)

2016-12-01 02:22 429 查看
这道题的传统思路是想方法把根到两个点的路径分别保存在两个容器中,然后从后往前遍历容器找出相等的节点便为最近公共祖先。很容易计算出这是一个时间复杂度为o(n),空间复杂度为o(lgn)的算法。

如果我们这时要求使用空间复杂度为o(1)的算法那?

我们可以这样做: 假设2个节点为p1, p2。

我们遍历这颗树,如果发现这个节点为p1/p2或者这个

节点的子树中有p1/p2时,返回p1/p2。否则为NULL.

在这里注意,如果一个节点的左右子树都返回一个非NULL值,那么这个节点一定为p1,p2的最近公共祖先。

这时我们返回这个节点。



上面是一种情况,如果p1/p2是p2/p1的祖先那?

如果p1为p2的祖先,那么遍历到p1时便会返回而不会遍历p1子树。那么不会有节点的左右子树都不为NULL,只会返回p1,而p1正好是它们的最近公共祖先。

代码为下:

//节点结构
template<class T>
struct TreeNode
{
typedef TreeNode Node;
TreeNode() {};
TreeNode(const T& value)
:_left(NULL)
,_right(NULL)
,_value(value)
{

}

T _value;
Node *_left;
Node *_right;

};
Node *nearset_parents(const Node*&first,
const Node*&second)
{
//_root为根节点
nearset_parents(_root, first, second);
}

Node *nearset_parents(Node *root,const Node *&first,const Node *&second)
{
if (NULL == root)
return NULL:

if (first == root || second == root)
return root;

Node *p = parents(root->_left, first, second);
Node *pi = parents(root->_right, first, second);

if (p != NULL && pi != NULL)
return root;

return NULL == p ? pi, p;
}


这个解法有一个缺陷,如果所给的·p1/p2不在树中,将会出现错误答案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息