思路:使用map存储每个节点的父节点,则两个节点的最近公共祖先,即二者的最近父节点
1、中序遍历二叉树(当前节点的下一个节点)
2、记录每个节点的父节点
3、列出p的族谱、q的族谱
4、寻找二者最近的祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode n1, TreeNode n2) {
if (n1.val == root.val || n2.val == root.val) {
return root;
}
// 1.寻找所所有节点的父节点
Map<TreeNode, TreeNode> map = new HashMap<>();
findParent(map, root);
// 2.n1的家谱(包括自己)
List<TreeNode> n1ParentList = getPeople(map, n1);
// 3.n2的家谱
List<TreeNode> n2ParentList = getPeople(map, n2);
// 4.n1和n2的公共长辈的第一个长辈
n1ParentList.retainAll(n2ParentList);
return n1ParentList.get(0);
}
private void findParent(Map<TreeNode, TreeNode> map, TreeNode root) {
map.put(root, null);
TreeNode temp = root;
// 1.最左子节点
while (temp.left != null) {
map.put(temp.left, temp);
temp = temp.left;
}
// 2.下一个节点
TreeNode curNode = temp;
while (true) {
TreeNode nextNode = next(map, curNode);
if (nextNode == null) {
return;
}
curNode = nextNode;
}
}
private TreeNode next(Map<TreeNode, TreeNode> map, TreeNode curNode) {
if (curNode.right != null) {
TreeNode next = curNode.right;
map.put(next, curNode);
while (next.left != null) {
map.put(next.left, next);
next = next.left;
}
return next;
} else {
TreeNode parent = map.get(curNode);
while (true) {
if (parent == null) {
return null;
} else if (parent.left != null && Objects.equals(parent.left.val, curNode.val)) {
return parent;
} else {
curNode = parent;
parent = map.get(curNode);
}
}
}
}
private List<TreeNode> getPeople(Map<TreeNode, TreeNode> map, TreeNode node) {
List<TreeNode> list = new ArrayList<>();
while (node != null) {
list.add(node);
TreeNode parent = map.get(node);
node = parent;
}
return list;
}
}