二叉树节点的最近邻公共祖先节点
介绍
求一个二叉树中两个节点的最近邻公共祖先节点(LCA
According to the definition of LCA on Wikipedia: “The lowest common
ancestor is defined between two nodes v and w as the lowest node in T
that has both v and w as descendants (where we allow a node to be a
descendant of itself).”
)。旨在掌握递归的运用,练习题目为LeetCode第235题与第236题。
235. BST的LCA
_______6______
/ \
__2___ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
BST的特点是结点的左子树上的所有结点的值都不大于它,右子树上所有结点的值都比它大。
因此对于要寻找LCA的两个结点p,q,根节点的值r有:
- 如果结点值p,q>r,则p,q都是r的右子树上的节点;
- 如果结点值p,q≤r,则p,q都是r的左子树上的节点;
- 如果结点值p≤r≤q,则r为p,q的LCA。
具体实现代码为:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root->val == p->val || root->val == q->val)
return root;
bool l1 = root->val > p->val;
bool l2 = root->val > q->val;
if (l1 && l2)
lowestCommonAncestor(root->left, p, q);
else if (l1 || l2)
return root;
else
lowestCommonAncestor(root->right, p, q);
}
};
236. BT的LCA
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
BT没有BST那样方便的通过判断结点值大小就能判断结点位置的性质,不过如果我们能够找到结点的中序遍历顺序的话,也就能吧BT转化成BST。但是这样做的弊端是需要在每个结点中加入一个记录中序遍历顺序的变量,也需要体现对二叉树进行一次中序遍历,这并不是我们想要的结果。
现在我们转换一种思维,根结点r与待求结点p,q只有3中关系,也就是235中利用的
- p,q都在r的左子树上;
- p,q都在r的右子树上;
- p,q分别在r的两个子树上,此时r为p,q的LCA。
前两种情况,都可以递归的寻找子树上的第三种情况,因此递归即可完成。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == p || root == q || root == NULL) return root;
TreeNode *lNode = lowestCommonAncestor(root->left, p, q);
TreeNode *rNode = lowestCommonAncestor(root->right, p , q);
if (lNode && rNode) return root;
else if(lNode) return lNode;
else return rNode;
}
};