树中两个结点的最低公共祖先
题目:
给出一个二叉树,输入两个树节点,求它们的最低公共祖先。
一个树节点的祖先节点包括它本身。
题目分析:
两个树结点的最低公共祖先有两种情况,这里假设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 };