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

题目:

给出一个二叉树,输入两个树节点,求它们的最低公共祖先。

一个树节点的祖先节点包括它本身。

 

题目分析:

两个树结点的最低公共祖先有两种情况,这里假设P为深度较浅的结点。

第一种情况是:P直接是Q的祖先之一,所以此时P为 P和Q的最低公共祖先

第二种情况是:P和Q分属于最低公共祖先的两边,此时回溯的第一个公共结节即为最低公共祖先。由于左右两图只是表示不同,实质相同,所以下面均使用左图作为情况二

 

解决方案:

二叉树一般可使用递归方法解决。递归时分别递归左右子树。

一般我们需要分别找到Q和P,然后再想办法找到它们的最低共同祖先。

递归遍历中找到Q或者P结点,则返回该结点作为返回值,如果目前遍历结点为空,则返回 NULL。

对于第一种情况, P是Q的最低共同祖先,此为我们递归遍历时,找到较浅的P就可以返回该结点作为该题的答案。此时较深的Q不会被访问。

对于第二种情况,遍历会访问到P和Q,如果访问到P或者Q,则将该结点作为结果返回至上一层。因为我们只会在访问到Q或者P时返回,所以在未找到最低公共祖先时,返回值一定是Q或者P。

 

如果将最低共同祖先作为回溯的最终结果?

每次遍历完左右子树后,判断左右子树的遍历情况,

如果左右子树均不为空,则返回该结点;

重点:找到最低公共祖先后,回溯后只有含有最低公共祖先的一侧的返回结果不为空,另一侧为空,

因此我们找到最低公共祖先后,只需要返回含有最低公共祖先的一侧,并且将含有最低公共祖先的结果作为返回结果。

第一种情况,在整个回溯过程中,返回结点并未改变。

第二种情况,在整个回溯过程中,返回结点会改变。当返回结点为最低公共祖先时,返回结点不变。

 

代码

 1 class Solution {
 2 public:
 3     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
 4         if(!root) return NULL;
 5         if(root == q || root == p) return root;
 6         auto left = lowestCommonAncestor(root->left, p, q);
 7         auto right = lowestCommonAncestor(root->right, p, q);
 8         if(left && right) return root;
 9         if(left) return left;
10         if(right) return right;
11     }
12 };

 

posted @ 2019-05-30 03:22  roov  阅读(13)  评论(0编辑  收藏  举报