首个共同祖先
难度:
标签:
题目描述
Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
For example, Given the following tree: root = [3,5,1,6,2,0,8,null,null,7,4]
3 / \ 5 1 / \ / \ 6 2 0 8 / \ 7 4
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Input: 3 Explanation: The first common ancestor of node 5 and node 1 is node 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The first common ancestor of node 5 and node 4 is node 5.
Notes:
- All node values are pairwise distinct.
- p, q are different node and both can be found in the given tree.
代码结果
运行时间: 38 ms, 内存: 20.4 MB
/*
* 思路:
* 使用 Java Stream 的概念解决此问题并不直接。
* 因为树的遍历和查找过程不符合 Stream 的惰性求值和不可变性的特点。
* 因此,标准递归解决方案更合适。
* 这里将代码转换为更具有函数式风格的写法。
*/
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return findLCA(root, p, q);
}
private TreeNode findLCA(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = findLCA(root.left, p, q);
TreeNode right = findLCA(root.right, p, q);
return (left != null && right != null) ? root : (left != null ? left : right);
}
}
解释
方法:
这个题解使用了递归的深度优先搜索(DFS)策略来寻找二叉树中两个节点的最低公共祖先。递归函数检查当前节点是否为null,如果是,则返回null。如果当前节点是p或q中的一个,则返回当前节点,表示找到了其中一个节点。然后,递归地在左右子树中查找p和q。如果在左子树中找到了p或q,并且在右子树中也找到了,那么当前节点就是p和q的最低公共祖先。如果只在左子树或右子树中找到了p或q,那么返回相应的非null结果。这个方法利用了二叉树的性质,通过递归来简化查找过程。
时间复杂度:
O(n)
空间复杂度:
O(h)
代码细节讲解
🦆
在`lowestCommonAncestor`方法中,如果p和q都不在树中会发生什么?函数将返回什么结果?
▷🦆
题解中提到,如果在左右子树中都找到了p或q,当前节点就是最低公共祖先。但如果p是q的祖先(或反之),递归会如何处理这种情况?
▷🦆
该算法是否能处理含有重复值节点的二叉树?如果树中存在多个具有相同值的节点,这种实现还是有效吗?
▷