二叉树:找出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正好是它们的最近公共祖先。
代码为下:
这个解法有一个缺陷,如果所给的·p1/p2不在树中,将会出现错误答案。
如果我们这时要求使用空间复杂度为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不在树中,将会出现错误答案。
相关文章推荐
- 在二叉树中,求任意两个节点的最近公共祖先(遍历的应用算法)
- 在二叉树中查找两个节点的最近的公共祖先节点(无回溯指针)(NCA--nearest common ancestor)
- 二叉树--求二叉树中两个节点的最近公共祖先
- 判断一棵树是否是完全二叉树和求二叉树中两个节点的最近公共祖先——题集(十三)
- 笔试算法题(24):找出出现次数超过一半的元素 & 二叉树最近公共父节点
- 求二叉树中两个节点的最近公共祖先
- 二叉树中任意两个节点的最近公共祖先节点
- 【学习点滴-数据结构-二叉树】求二叉树中某两个节点的最近公共祖先
- 4.6-二叉树的2个节点的第一个公共祖先节点
- 求二叉树的任意两个节点的最近公共祖先
- 设计算法查找二叉树的两个结点最近公共祖先(LCA)
- [置顶] 寻找二叉树两节点的最近的公共祖先[转载+整理]
- 【数据结构】二叉树中任意两节点的最近公共祖先节点
- 找出二叉树中某两个节点的第一个公共祖先
- 在二叉树中找到两个节点的最近公共祖先
- 二叉树中两个节点的最近公共祖先节点
- 二叉树两个节点求最近的公共祖先节点java代码实现
- 求两个节点的最近公共祖先多种解法&&判断一个节点是否在二叉树中
- 二叉树中两个节点的最近公共祖先节点
- 二叉树中两个节点的最近公共祖先节点