236. Lowest Common Ancestor of a Binary Tree
一、题目
1、审题
2、分析
求二叉树中 p、q 节点的最小共同祖先节点。
二、解答
1、思路
方法一、
采用循环查找。
①、若 root 为 p 或者 q ,则返回 root
②、若 p、q 分布在 root 不同的左右子树,则返回 root
③、若 p、q 均为 root 左子树,则 root = root.left; 若 p、q均在右子树,则 root = root.right。
1 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 2 while(root != null) { 3 if(root.val == p.val || root.val == q.val) 4 return root; 5 6 boolean pInLeft = isChildren(root.left, p); 7 boolean qInRight = isChildren(root.right, q); 8 9 if((pInLeft && qInRight) || (!pInLeft && !qInRight)) 10 return root; 11 12 if(pInLeft) // p、q 均在 left 13 root = root.left; 14 else // p、q 均在 right 15 root = root.right; 16 } 17 return null; 18 } 19 20 private boolean isChildren(TreeNode root, TreeNode p) { 21 TreeNode node = root; 22 while(node != null) { 23 if(node.val == p.val) 24 return true; 25 else 26 return isChildren(root.left, p) || isChildren(root.right, p); 27 } 28 return false; 29 }
方法二、
采用递归查找。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if(left == null) return right; if(right == null) return left; // 分别在左右子树 return root; }
方法三、
采用 Map 存储每个节点和该节点的父节点。
最终采用 Set 存储 p 的所有祖先节点,q依次向祖先节点移动,找出第一次出现在 Set 中的节点即为 p、q 最小祖先节点。
1 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 2 HashMap<TreeNode, TreeNode> parent = new HashMap<>(); 3 Deque<TreeNode> stack = new ArrayDeque<TreeNode>(); 4 parent.put(root, null); 5 stack.push(root); 6 7 // paretn 同时包含 p、q 则跳出循环 8 while(!parent.containsKey(p) || !parent.containsKey(q)) { 9 TreeNode node = stack.pop(); 10 if(node.left != null) { 11 parent.put(node.left, node); 12 stack.push(node.left); 13 } 14 15 if(node.right != null) { 16 parent.put(node.right, node); 17 stack.push(node.right); 18 } 19 } 20 21 Set<TreeNode> ancestors = new HashSet<>(); 22 while(p != null) { 23 ancestors.add(p); 24 p = parent.get(p); 25 } 26 while(!ancestors.contains(q)) 27 q = parent.get(q); 28 return q; 29 }