• 【Leetcode】236. Lowest Common Ancestor of a Binary Tree


    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

    According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

            _______3______
           /              
        ___5__          ___1__
       /              /      
       6      _2       0       8
             /  
             7   4
    

    For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

    Tips:求一颗普通二叉树中两个结点的最低公共子节点。

    解法一:分别求出从根节点到两个子节点的路径,在根据两个路径找到两个结点的最后一个公共结点。

    package medium;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import dataStructure.TreeNode;
    
    public class L236LowestCommonAncestorOfaBT {
        
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            // 求解方式:找到从根节点到两个叶子节点pq的路径,根据两条路径找到第一个公共子结点。
            if (root == null || root == p || root == q)
                return root;
            List<TreeNode> path1 = new ArrayList<TreeNode>();
            getPath(root, p, path1);
            List<TreeNode> path2 = new ArrayList<TreeNode>();
            getPath(root, q, path2);
            TreeNode ans = getCommanNode(path1, path2);
            return ans;
        }
    
        private TreeNode getCommanNode(List<TreeNode> path1, List<TreeNode> path2) {
            // TODO Auto-generated method stub
            int len1 = path1.size();
            int len2 = path2.size();
            int i;
            for (i = 0; i < len1 && i < len2; i++) {
                if (path1.get(i).val != path2.get(i).val) {
                    return path1.get(i - 1);
                }
            }
            return path1.get(i - 1);
        }
    
        public boolean getPath(TreeNode root, TreeNode p, List<TreeNode> path) {
            // TODO 求根节点到p、q结点的路径
            path.add(root);
            if (root == p) {
                return true;
            }
    
            boolean found = false;
            if (root.left != null) {
                found = getPath(root.left, p, path);
                if (found == true)
                    return true;
            }
            if (root.right != null) {
                found = getPath(root.right, p, path);
                if (found == true)
                    return true;
            }
    
            path.remove(root);
            return found;
        }
    
        public static void main(String[] args) {
            TreeNode n1 = new TreeNode(1);
            TreeNode n2 = new TreeNode(2);
            TreeNode n3 = new TreeNode(3);
            n1.left = null;
            n1.right = n2;
            n2.left = null;
            n2.right = n3;
    
            TreeNode n4 = null;
            TreeNode n5 = null;
            n3.left = n4;
            n3.right = n5;
            L236LowestCommonAncestorOfaBT l236 = new L236LowestCommonAncestorOfaBT();
            //测试getPath()函数
            List<TreeNode> path1 = new ArrayList<TreeNode>();
            l236.getPath(n1, n3, path1);
            for (int i = 0; i < path1.size(); i++) {
                System.out.println(path1.get(i).val);
            }
            List<TreeNode> path2 = new ArrayList<TreeNode>();
            l236.getPath(n1, n2, path2);
            for (int i = 0; i < path2.size(); i++) {
                System.out.println(path2.get(i).val);
            }
            System.out.println("~~~~~~~~~~~~~~");
            //测试求公共结点函数 getCommanNode()
            TreeNode com = l236.getCommanNode(path1, path2);
            System.out.println("getCom祖先:" + com.val);
            System.out.println("~~~~~~~~~~~~~");
            //lowestCommonAncestor()函数
            TreeNode comTreeNode = l236.lowestCommonAncestor(n1, n2, n3);
            System.out.println("公共祖先为:" + comTreeNode.val);
            TreeNode node1 = new TreeNode(1);
            TreeNode node2 = new TreeNode(2);
            n1.left = null;
            n1.right = n2;
            n2.left = null;
            n2.right = null;
            System.out.println("~~~~~~~~~~~~~~~~~~");
            TreeNode comTreeNode1 = l236.lowestCommonAncestor(node1, node1, node2);
            System.out.println("case2:" + comTreeNode1.val);
        }
    }

    解法二:递归

    在root的左右子树中找p、q,如果left跟right都不为为空,证明p、q分别在左右子树,那么他们的公共祖先就是root。

    如果left中有一个为空,那么不为空的那个就是公共祖先。

    public TreeNode lowestCommonAncestor2(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 && right != null)
                return root;
            return left != null ? left : right;
        }
  • 相关阅读:
    spring data jpa 动态查询(mysql)
    C#面向对象15 多态
    Visual Studio 2012网站如何只生成一个DLL文件
    C#面向对象14 List泛型集合/装箱和拆箱/字典集合(Dictionary)
    C#面向对象13 文件类操作 Path/File/FileStream
    C#面向对象12 集合
    C#面向对象11 里氏转换
    C#面向对象10 继承
    C#面向对象9 字符串
    C# 面向对象8 值类型和引用类型
  • 原文地址:https://www.cnblogs.com/yumiaomiao/p/8443354.html
Copyright © 2020-2023  润新知