zoukankan      html  css  js  c++  java
  • 【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;
        }
  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/yumiaomiao/p/8443354.html
Copyright © 2011-2022 走看看