描述
给定一棵二叉树(保证非空)以及这棵树上的两个节点对应的val值 o1 和 o2,请找到 o1 和 o2 的最近公共祖先节点。
注:本题保证二叉树中每个节点的val值均不相同。
示例1
输入:
[3,5,1,6,2,0,8,#,#,7,4],5,1
返回值:
3
解法一
- 1,使用层序遍历,直到找到两个结点为止
- 2,层序遍历过程中,将子节点与父节点组成的键值对保存在Map中
- 3,遍历Map,将o1的所有父节点保存到集合中List中
- 4,遍历Map,逐个判断o2的父节点是否存在于o1的父节点集合中,如果存在,则二者有相同的父节点
思考:如何保证最后找到的是最近的父节点
因为对于o2的遍历是从下向上的,每次判断的都是离o2最低的父节点,则找出来的也是二者的最近父节点
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
// 1,遍历找到o1和o2
// 2,找到o1的所有父节点集合
// 3,判断o2的父节点是否存在于o1的父节点集合
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
Map<Integer,Integer> nodes = new HashMap<>();
nodes.put(root.val,Integer.MAX_VALUE);
while(queue.size() > 0 && (!nodes.containsKey(o1) || !nodes.containsKey(o2))) {
TreeNode parent = queue.poll();
if (parent.left != null) {
queue.add(parent.left);
nodes.put(parent.left.val, parent.val);
}
if (parent.right != null) {
queue.add(parent.right);
nodes.put(parent.right.val, parent.val);
}
}
List<Integer> parents = new ArrayList<>();
// 结点的父节点可能是结点本身,所以o1自身也要放入结点的父节点集合中
while (o1 != Integer.MAX_VALUE) {
parents.add(o1);
o1 = nodes.get(o1);
}
while (!parents.contains(o2)) {
o2 = nodes.get(o2);
}
return o2;
}