给定一棵二叉树的根节点 root
,返回给定节点 p
和 q
的最近公共祖先(LCA)节点。如果 p
或 q
之一 不存在 于该二叉树中,返回 null
。树中的每个节点值都是互不相同的。
根据维基百科中对最近公共祖先节点的定义:“两个节点 p
和 q
在二叉树 T
中的最近公共祖先节点是 后代节点 中既包括 p
又包括 q
的最深节点(我们允许 一个节点为自身的一个后代节点 )”。一个节点 x
的 后代节点 是节点 x
到某一叶节点间的路径中的节点 y
。
示例 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。根据共同祖先节点的定义,一个节点可以是自身的后代节点。
示例 3:
输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 10 输出: null 解释: 节点 10 不存在于树中,所以返回 null。
提示:
- 树中节点个数的范围是
[1, 104]
-109 <= Node.val <= 109
- 所有节点的值
Node.val
互不相同 p != q
进阶: 在不检查节点是否存在的情况下,你可以遍历树找出最近公共祖先节点吗?
我们设计一个函数 true
,否则返回 false
。
函数
如果当前节点 false
。
否则,我们递归地遍历左子树和右子树,得到
如果 true
,说明当前节点
如果 true
,并且当前节点
最后,我们判断 true
,或者当前节点 true
,否则返回 false
。
时间复杂度
# 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':
def dfs(root, p, q):
if root is None:
return False
l = dfs(root.left, p, q)
r = dfs(root.right, p, q)
nonlocal ans
if l and r:
ans = root
if (l or r) and (root.val == p.val or root.val == q.val):
ans = root
return l or r or root.val == p.val or root.val == q.val
ans = None
dfs(root, p, q)
return ans
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private TreeNode ans;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
dfs(root, p, q);
return ans;
}
private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return false;
}
boolean l = dfs(root.left, p, q);
boolean r = dfs(root.right, p, q);
if (l && r) {
ans = root;
}
if ((l || r) && (root.val == p.val || root.val == q.val)) {
ans = root;
}
return l || r || root.val == p.val || root.val == q.val;
}
}
/**
* 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) {
dfs(root, p, q);
return ans;
}
private:
TreeNode* ans = nullptr;
bool dfs(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root) {
return false;
}
bool l = dfs(root->left, p, q);
bool r = dfs(root->right, p, q);
if (l && r) {
ans = root;
}
if ((l || r) && (root->val == p->val || root->val == q->val)) {
ans = root;
}
return l || r || root->val == p->val || root->val == q->val;
}
};
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {TreeNode} p
* @param {TreeNode} q
* @return {TreeNode}
*/
var lowestCommonAncestor = function (root, p, q) {
const dfs = root => {
if (!root) {
return false;
}
const l = dfs(root.left);
const r = dfs(root.right);
if (l && r) {
ans = root;
}
if ((l || r) && (root.val === p.val || root.val === q.val)) {
ans = root;
}
return l || r || root.val === p.val || root.val === q.val;
};
let ans = null;
dfs(root);
return ans;
};