236. 二叉树的最近公共祖先
题目描述:
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 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 = [1,2], p = 1, q = 2
输出:1
提示:
- 树中节点数目在范围 [2, 10^5] 内。
- -10^9 <= Node.val <= 10^9
- 所有 Node.val 互不相同 。
- p != q
- p 和 q 均存在于给定的二叉树中。
解题分析及思路:
这道题考察的是二叉树的遍历,不熟悉二叉树的遍历可以查看二叉树。
方法:深度优先搜索
两个节点 p,q 在一棵树中分布可以分为两种情况:
- p 和 q 在相同子树中
- p 和 q 在不同子树中
那么可以采用深度优先搜索的方法,对于某个节点node
- 如果p或q为node,那么node就是最近公共祖先
- 否则,递归遍历左右子树,如果左右子树都不为空,那么node就是最近公共祖先
- 如果左右子树其中一个不为空,则返回非空节点(因为一棵树内,暂无匹配的节点,那么将会返回空节点)。
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
if root == nil {
return nil
}
if root.Val == p.Val || root.Val == q.Val {
return root
}
left := lowestCommonAncestor(root.Left, p, q)
right := lowestCommonAncestor(root.Right, p, q)
if left != nil && right != nil {
return root
}
if left == nil {
return right
}
return left
}
复杂度:
- 时间复杂度:O(N),其中 N 是树中的节点个数
- 空间复杂度:O(N)
执行结果:
- 执行耗时:9 ms,击败了38.26% 的Go用户
- 内存消耗:6.7 MB,击败了66.26% 的Go用户