「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
235. 二叉搜索树的最近公共祖先
题目描述
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
复制代码
示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
复制代码
解析
自底向上查找就可以找到公共祖先了
二叉树回溯的过程可以实现自底向上查找
后序遍历就是天然的回溯过程,最先处理的一定是叶子节点
如果找到一个节点,该节点的左子树上出现节点p ,右子树上出现节点q
那么这个节点就是p q 的公共祖先
递归三部曲
1、确定递归函数的参数与返回值
需要递归函数的返回值来确定是否找到了p 或 q节点
那么返回值类型可以是bool类型
但是还需要返回最近的公共节点,所以可以直接返回p 或 q
返回值不为空,就说明找到了 p 或 q
2、确定终止条件
如果遇到了节点p 或 q 或是NULL ,就直接返回
3、单层递归的逻辑
本题递归函数需要返回值,使用 left接左子树的递归结果,使用 right 接右子树的递归结果。
复制代码
代码
class Solution
{
public:
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p.TreeNode *q)
{
if (root == p || root == q || root == NULL)
{
return root;
}
TreeNode *left = lowestCommonAncestor(root->left, p, q);
TreeNode *right = lowestCommonAncestor(root->right, p, q);
// 如果 left和right都不为空,则说明 root 就是最近的公共节点
if (left != NULL && right != NULL)
{
return root;
}
// 如果 left 为空 right 不为空,则返回right
else if (left == NULL && right != NULL)
{
return right;
}
// 如果 right 为空 left 不为空,则返回left
else if (left != NULL && right == NULL)
{
return right;
}
else
{
return NULL;
}
}
};
复制代码