题目
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉树中。
解题思路
具体思路:
(1) 如果当前结点 root 等于NULL,则直接返回NULL
(2) 如果 root 等于 p 或者 q ,那这棵树一定返回 p 或者 q
(3) 然后递归左右子树,因为是递归,使用函数后可认为左右子树已经算出结果,用 left 和 right表示
(4) 此时若left为空,那最终结果只要看 right;若 right 为空,那最终结果只要看 left
(5) 如果 left 和 right 都非空,因为只给了 p 和 q 两个结点,都非空,说明一边一个,因此 root 是他们的最近公共祖先
(6) 如果 left和 right 都为空,则返回空(其实前面第4种情况已经包含了)。
复杂度分析:
时间复杂度:O(n),每个结点最多遍历一次。
空间复杂度:O(n),需要用到系统栈空间。
代码
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 root == p or root == q:
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
# 以下参考剑指offer写法,超时
# class Solution:
# def getNodePath(self, root, node, path):
# if root==node:
# return True
# path.append(root)
# flag = False
# while(flag==False and root):
# flag = self.getNodePath(root.left, node, path)
# flag = self.getNodePath(root.right, node, path)
# if(flag==False):
# path.pop()
# return flag
# def getLastCommonNode(self, l1, l2):
# len1 = len(l1)
# len2 = len(l2)
# i = 0
# j = 0
# commonNode = None
# while(i<len1 and j<len2):
# if(l1[i]==l2[j]):
# commonNode = l1[i]
# i += 1
# j += 1
# return commonNode
# def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# path1 = []
# path2 = []
# self.getNodePath(root, p, path1)
# self.getNodePath(root, q, path2)
# return self.getLastCommonNode(path1, path2)
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 || 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;
}
}
本文介绍了一种解决二叉树中寻找两个指定节点最近公共祖先问题的方法。通过递归遍历二叉树,利用左、右子树的返回结果判断当前节点是否为最近公共祖先。文章提供了Python和Java实现代码,并分析了算法的时间和空间复杂度。

804

被折叠的 条评论
为什么被折叠?



