网站救助计划
1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本
2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助,网站倒闭后可联系站长领取本站pdf内容
3.若网站能存活下来,后续将会持续更新内容
题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大( 一个节点也可以是它自己的祖先 )。”
例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]
示例 1:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共祖先是节点 3。
示例 2:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉树中。
题解
(递归) O(n)
求公共祖先需要自底向上递归遍历二叉树,那么可以按照后序顺序遍历。
题目已知 p 和 q 一定在二叉树中,所以一定存在非空答案。
递归三部曲:
- 递归函数的含义:直接使用题目给出的函数,返回以 root 为根节点二叉树中节点 p 和 q 的最近公共祖先,返回值就是最近公共祖先。返回值总共有四种情况:
- 如果以 root 为根的子树中包含 p 和 q,则返回它们的最近公共祖先即 root
- 如果只包含 p,返回 p
- 如果只包含 q,返回 q
- 如果都不包含,则返回 NULL
- 递归出口条件:如果当前节点 root 为空或等于 p 或等于 q,直接返回当前节点即可。
- 如果
root == NULL
说明没找到 p 或 q,返回 NULL 即可 - 如果
root == p
说明当前树包含 p,p 是它自己的最近公共祖先,返回 p - 如果
root == q
说明当前树包含 q,q 是它自己的最近公共祖先,返回 q
- 如果
- 单层递归逻辑:递归查找左子树中 p 和 q 的最近公共祖先 left,递归查找右子树中 p 和 q 的最近公共祖先 right,所以对于 left 和 right 有四种情况:
- 如果 left 为空,最近公共祖先一定在右子树中,返回 right 即可。
- 如果 right 为空,最近公共祖先一定在左子树中,返回 left 即可。
- 如果 left 和 right 都不为空,则返回当前节点
- 如果 left 和 right 都为空,则返回空,这种情况可以在第一种情况中得到处理。
时间复杂度
二叉树中的每个节点只需被遍历一次,所以时间复杂度为 O(n)。
空间复杂度
最坏情况下二叉树呈链状,需要 O(n) 的空间。
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 (p == root || q == root || !root) return root;
auto left = lowestCommonAncestor(root->left, p, q);
auto right = lowestCommonAncestor(root->right, p, q);
if (!left) return right;
if (!right) return left;
return root;
}
};
Java 代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || p == root || q == root) {
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;
}
return root;
}
}
Python 代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or p == root or q == root:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left:
return right
if not right:
return left
return root
本文由读者提供,Github地址:https://github.com/tonngw
点击面试手册,获取本站面试手册PDF完整版