zoukankan      html  css  js  c++  java
  • Leetcode 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.


    解题思路:

    本题寻找是binary tree的LCA, 因此难度比binary search tree 增大了。很容易出错,也很容易想不清楚,记住!!

    两种方法:
    1. recursion

    A Bottom-up Approach (Worst case O(n) ):

    Using a bottom-up approach, we can improve over the top-down approach by avoiding traversing the same nodes over and over again.

    We traverse from the bottom, and once we reach a node which matches one of the two nodes, we pass it up to its parent. The parent would then test its left and right subtree if each contain one of the two nodes. If yes, then the parent must be the LCA and we pass its parent up to the root. If not, we pass the lower node which contains either one of the two nodes (if the left or right subtree contains either p or q), or NULL (if both the left and right subtree does not contain either p or q) up.

    2. use two stacks, find two nodes separately and compare their traces, the LCA will be the first element to push into its stack, the LCA's parent, till the root. When pop(), you will from root to child....When find the first different node, the node before it will be the LCA of p and q. 


    Java code:

    1. recursion:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            //recursion
            if(root == null || root == p || root == q) { return root; }
            TreeNode l = lowestCommonAncestor(root.left, p, q);
            TreeNode r = lowestCommonAncestor(root.right, p, q);
            if(l!=null && r!= null) return root; // if p and q are on both sides
            return (l!=null)? l: r; //either one of p, q is on one side OR p,q is not in l&r subtrees
        }
    }

    2. use two stacks

    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            Stack<TreeNode> sp = new Stack<TreeNode>();
            Stack<TreeNode> sq = new Stack<TreeNode>();
            findNode(root, p, sp);
            findNode(root, q, sq);
            TreeNode target = root;
            TreeNode temp;
            while(!sp.isEmpty() && !sq.isEmpty()){
                temp = sp.pop();
                if(temp == sq.pop()) {
                    target = temp;
                }
                else{
                    break;
                }
            }
            return target;
        }
        
        public boolean findNode(TreeNode root, TreeNode p, Stack<TreeNode> s) {
            if(root == null) {
                return false;
            }
            if(root == p) {
                s.push(root);
                return true;
            }else if(findNode(root.left, p, s) || findNode(root.right, p,s)) {
                s.push(root);
                return true;
            }else{
                return false;
            }
        }
    }

    Reference:

    1. http://articles.leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html

    2. https://leetcode.com/discuss/49255/share-my-java-solution-using-stack-easy-to-understand

  • 相关阅读:
    spring Bean的生命周期
    java合并两个有序数组的算法(抛砖引玉)
    Spring 中解析 URL参数的几种方式
    联合索引和单个索引使用注意事项
    Java中同一个类中不同的synchronized方法是否可以并发执行?
    简析JVM GC的根搜索算法
    spring rest 请求怎样添加Basic Auth请求頭
    spring boot 排除个别配置类的代码
    使用非对称算法RSA实现加解密和使用签名算法SHA1WithRSA、MD5withRSA生成签名以及验签
    Redis中如何发现并优化big key?
  • 原文地址:https://www.cnblogs.com/anne-vista/p/4815076.html
Copyright © 2011-2022 走看看