思路:使用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;}
}