二叉树的最近公共祖先 IV
难度:
标签:
题目描述
代码结果
运行时间: 71 ms, 内存: 20.3 MB
/*
题目思路:
1. 与普通的Java解法相同,但在处理节点集合时使用流(Stream)API。
2. 将节点的值收集到一个Set中,然后递归寻找LCA。
*/
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode[] nodes) {
Set<Integer> values = Stream.of(nodes).map(node -> node.val).collect(Collectors.toSet());
return findLCA(root, values);
}
private TreeNode findLCA(TreeNode root, Set<Integer> values) {
if (root == null) return null;
if (values.contains(root.val)) return root;
TreeNode left = findLCA(root.left, values);
TreeNode right = findLCA(root.right, values);
if (left != null && right != null) return root;
return left != null ? left : right;
}
}
解释
方法:
这个题解使用了递归的深度优先搜索(DFS)来寻找最近公共祖先。函数`dfs`从二叉树的根节点开始,向下遍历每一个节点。如果当前节点为空,返回`None`。如果当前节点是待查询的节点列表`nodes`中的一个,直接返回该节点。然后递归地在左右子树上调用`dfs`函数,得到左子树和右子树的返回结果`l`和`r`。如果某一侧返回了`None`,说明这一侧没有找到任何`nodes`中的节点,因此返回另一侧的结果。如果两侧都返回了非`None`的结果,说明当前节点是两个子树返回的节点的公共祖先,因此返回当前节点。这个递归过程持续进行,直到遍历完所有节点,或找到最近的公共祖先。
时间复杂度:
O(n)
空间复杂度:
O(h + k)
代码细节讲解
🦆
如何处理`nodes`列表中包含重复节点的情况?是否会影响算法的结果或性能?
▷🦆
在递归函数`dfs`中,你是如何判断一个节点是否属于`nodes`列表的?使用什么数据结构可以优化这一查找过程?
▷🦆
如果输入的二叉树非常倾斜(例如所有节点都在左侧或右侧),递归深度将会非常深。在这种情况下,如何优化代码以防止栈溢出?
▷🦆
题解中提到如果两侧都返回了非`None`的结果,则当前节点是公共祖先。这是否意味着算法总是返回最近的公共祖先,还是可能返回较远的公共祖先?
▷