• 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

  • 相关阅读:
    Golden Tiger Claw (KM算法)
    Xor Sum题解>----(思维+递归)
    Mister B and PR Shifts(思维)
    Traffic Real Time Query System-(点双缩点+LCA)
    最大的位或----(极简代码)
    萌萌哒题解_倍增并查集
    连续攻击游戏(递增1)题解------(并查集)
    道路与航线 (连通块Dijkstra+拓扑序||spfa+slf优化)
    美团校招-表达式求值
    天猫前端电话面试
  • 原文地址:https://www.cnblogs.com/shan333/p/15709242.html
Copyright © 2020-2023  润新知