236_二叉树的最近公共祖先
236_二叉树的最近公共祖先
package 二叉树.BT; import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Set; /** * https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/ * @author Huangyujun * */ public class _236_二叉树的最近公共祖先 { /** * 方法1:存父节点的方式【因为使用了map 字典,存储父结点导致效率不高】 * @author Huangyujun * 思路:parent:【键:当前结点的值; 值:父结点】 * */ class Solution { Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>(); Set<Integer> visited = new HashSet<Integer>(); public void dfs(TreeNode root) { if (root.left != null) { parent.put(root.left.val, root); dfs(root.left); } if (root.right != null) { parent.put(root.right.val, root); dfs(root.right); } } public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { dfs(root); while (p != null) { visited.add(p.val); p = parent.get(p.val); } while (q != null) { if (visited.contains(q.val)) { return q; } q = parent.get(q.val); } return null; } } /** * 我的思路跟官网差不多,但是因为我少了父节点存储后的遍历,导致后边比较bug不断 */ Deque<TreeNode> p_stack = new LinkedList<>(); Deque<TreeNode> q_stack = new LinkedList<>(); TreeNode p; TreeNode q; public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { this.p = p; this.q = q; dfs1(root); dfs2(root); while(!p_stack.isEmpty() && !q_stack.isEmpty()) { if(p_stack.peekLast().val == q_stack.peekLast().val) { return p_stack.peekLast(); } p_stack.pollLast(); q_stack.pollLast(); } return null; } //问题出现在传入一个存储结点的栈,发生了递归,。。。。原因2:出现在比较结点长度不一致时,不是同步比较呀【舒服的方式时官网的方式】 private void dfs1(TreeNode root) { if(root == null) return; //前序遍历 if(root.val == p.val) { return; }else { p_stack.push(root); } dfs1(root.left); dfs1(root.right); } private void dfs2(TreeNode root) { if(root == null) return; //前序遍历 if(root.val == q.val) { return; }else { q_stack.push(root); } dfs2(root.left); dfs2(root.right); } /** * 方式2:递归 * @author Huangyujun * ○ 树形一:root为p,q中的一个,这时公共祖先为root ○ 树形二:p,q分别在root的左右子树上(p在左子树,q在右子树;还是p在右子树,q在左子树的情况都统一放在一起考虑)这时满足p,q的最近公共祖先的结点也只有root本身 ○ 树形三:p和q同时在root的左子树;或者p,q同时在root的右子树,这时确定最近公共祖先需要遍历子树来进行递归求解。 */ class Solution2 { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root==p||root==q) { //树形一:root为p,q中的一个,这时公共祖先为root return root; } if (root!=null){//否则,root 不是p、q 中其中的一个 【需要在两个子树中找到最近祖父】 TreeNode lNode=lowestCommonAncestor(root.left,p,q); TreeNode rNode=lowestCommonAncestor(root.right,p,q); if (lNode!=null&&rNode!=null) {//树形二:p,q分别在root的左右子树上 return root; }else if(lNode==null) {//树形三:p和q同时在root的右子树 return rNode; } else { //树形三:p和q同时在root的左子树 return lNode; } } return null; } } }
本文来自博客园,作者:一乐乐,转载请注明原文链接:https://www.cnblogs.com/shan333/p/15709242.html