题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科 中最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉树中。
注意:本题与主站 236 题相同:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/
解法
方法一:递归
根据“最近公共祖先 ”的定义,若 \(root\) 是 \(p\) , \(q\) 的最近公共祖先,则只可能为以下情况之一:
如果 \(p\) 和 \(q\) 分别是 \(root\) 的左右节点,那么 \(root\) 就是我们要找的最近公共祖先;
如果 \(p\) 和 \(q\) 都是 \(root\) 的左节点,那么返回 \(lowestCommonAncestor(root.left, p, q)\) ;
如果 \(p\) 和 \(q\) 都是 \(root\) 的右节点,那么返回 \(lowestCommonAncestor(root.right, p, q)\) 。
边界条件讨论 :
如果 \(root\) 为 null
,则说明我们已经找到最底了,返回 null
表示没找到;
如果 \(root\) 与 \(p\) 相等或者与 \(q\) 相等,则返回 \(root\) ;
如果左子树没找到,递归函数返回 null
,证明 \(p\) 和 \(q\) 同在 \(root\) 的右侧,那么最终的公共祖先就是右子树找到的结点;
如果右子树没找到,递归函数返回 null
,证明 \(p\) 和 \(q\) 同在 \(root\) 的左侧,那么最终的公共祖先就是左子树找到的结点。
时间复杂度 \(O(n)\) ,空间复杂度 \(O(n)\) 。其中 \(n\) 是二叉树的节点数。
Python3 Java C++ Go TypeScript Rust JavaScript Swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 # 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 root is None or root == p or root == q :
return root
left = self . lowestCommonAncestor ( root . left , p , q )
right = self . lowestCommonAncestor ( root . right , p , q )
if left is None :
return right
if right is None :
return left
return root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 /**
* 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 || 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 ;
return root ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 /**
* 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 ) {
// 如果找到val,层层向上传递该root
if ( nullptr == root || p -> val == root -> val || q -> val == root -> val ) {
return root ;
}
TreeNode * left = lowestCommonAncestor ( root -> left , p , q );
TreeNode * right = lowestCommonAncestor ( root -> right , p , q );
if ( left != nullptr && right != nullptr ) {
// 如果两边都可以找到
return root ;
} else if ( left == nullptr ) {
// 如果左边没有找到,则直接返回右边内容
return right ;
} else {
return left ;
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14 func lowestCommonAncestor ( root , p , q * TreeNode ) * TreeNode {
if root == nil || root == p || root == q {
return root
}
left := lowestCommonAncestor ( root . Left , p , q )
right := lowestCommonAncestor ( root . Right , p , q )
if left == nil {
return right
}
if right == nil {
return left
}
return root
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 /**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function lowestCommonAncestor (
root : TreeNode | null ,
p : TreeNode | null ,
q : TreeNode | null ,
) : TreeNode | null {
if ( root == null || root === p || root === q ) {
return root ;
}
const left = lowestCommonAncestor ( root . left , p , q );
const right = lowestCommonAncestor ( root . right , p , q );
if ( left == null && right == null ) {
return null ;
}
if ( left == null ) {
return right ;
}
if ( right == null ) {
return left ;
}
return root ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 // Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
// pub val: i32,
// pub left: Option<Rc<RefCell<TreeNode>>>,
// pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
// #[inline]
// pub fn new(val: i32) -> Self {
// TreeNode {
// val,
// left: None,
// right: None
// }
// }
// }
use std :: cell :: RefCell ;
use std :: rc :: Rc ;
impl Solution {
pub fn lowest_common_ancestor (
root : Option < Rc < RefCell < TreeNode >>> ,
p : Option < Rc < RefCell < TreeNode >>> ,
q : Option < Rc < RefCell < TreeNode >>> ,
) -> Option < Rc < RefCell < TreeNode >>> {
if root . is_none () || root == p || root == q {
return root ;
}
let left = Self :: lowest_common_ancestor (
root . as_ref (). unwrap (). borrow_mut (). left . take (),
p . clone (),
q . clone (),
);
let right = Self :: lowest_common_ancestor (
root . as_ref (). unwrap (). borrow_mut (). right . take (),
p . clone (),
q . clone (),
);
match ( left . is_none (), right . is_none ()) {
( true , false ) => right ,
( false , true ) => left ,
( false , false ) => root ,
( true , true ) => None ,
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 /**
* 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 ) {
if ( ! root || root == p || root == q ) return root ;
const left = lowestCommonAncestor ( root . left , p , q );
const right = lowestCommonAncestor ( root . right , p , q );
if ( ! left ) return right ;
if ( ! right ) return left ;
return root ;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /* public class TreeNode {
* public var val: Int
* public var left: TreeNode?
* public var right: TreeNode?
* public init() { self.val = 0; self.left = nil; self.right = nil; }
* public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
* public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
* self.val = val
* self.left = left
* self.right = right
* }
* }
*/
class Solution {
func lowestCommonAncestor ( _ root : TreeNode ?, _ p : TreeNode , _ q : TreeNode ) -> TreeNode ? {
if root == nil || root === p || root === q {
return root
}
let left = lowestCommonAncestor ( root ?. left , p , q )
let right = lowestCommonAncestor ( root ?. right , p , q )
if let _ = left , let _ = right {
return root
}
return left ?? right
}
}