原题链接:236. 二叉树的最近公共祖先
题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
思路:参考【C++ 经典递归】思路非常好理解 时间复杂度O(n), 空间复杂度O(n)。
这里的思路是主要有三种情况:①两个结点都存在的话,则找出他们的最近公共祖先;②一个结点存在,另一个结点不存在的话,则最近公共祖先就是存在的这个结点;③两个结点都不存在的话,则最近公共祖先不存在(NULL)。
因此可以用递归的方式来求解。
递归的终止条件是:①结点为NULL;②结点本身等于所给的两个结点中的一个,返回这个结点即可。
递归左右子树,因为是递归,所以使用函数后可认为左右子树已经算出结果,用 leftleft 和 rightright 表示,即左右子树算出的所给结点的最近公共祖先。
然后我们判断 leftleft 和 rightright即可。
主要有以下三种情况:① leftleft 和 rightright其中一个为NULL,说明两个所给结点在同一边(要么在左,要么在右),此时我们返回 leftleft 和 rightright存在的那个即可(因为他们本身就是所求的最近公共最先);②两个结点都存在,说明两个结点一边一个,则最近公共结点为NULL;③两个结点都不存在,返回NULL即可。
递归的思路:①找出递归终止的条件;②送入下一层递归的参数;③当我们使用递归时,不要跟着陷进递归的层数里,我们默认此时的递归函数能算出结果,我们只需要关注递归的结果即可!
C++实现如下:
/**
* Definition for a binary tree node.
* 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==NULL)
return NULL;
if(root==p||root==q)
return root;
TreeNode *left=lowestCommonAncestor(root->left,p,q);
TreeNode *right=lowestCommonAncestor(root->right,p,q);
if(left==NULL)
return right;
if(right==NULL)
return left;
if(left&&right)
return root;
return NULL;
}
};