236. Lowest Common Ancestor of a Binary Tree



二刷。

先找了一下规律,对于一个点,无非2种情况:
PQ在左右两边,那么这个点就是答案
PQ在一边,那么答案啊在另一边上,迭代

Recursively.

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) 
    {
        if(root == null) return null;
        
        if(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 right;
        if(left != null && right == null) return left;
        if(right != null && right != null) return root;
        
        
        return null;
        
    }
}

然后回头看一刷用迭代做的。

应该可以,就是一层一层的来,找到其中一个的时候看看另一个在不在以当前为ROOT的树上,不在的话倒着找,需要2个队列,一个用来遍历,一个用来倒着找。




三刷。

还是递归。。。
从biary search tree变成了binary tree,不能通过value来判断在左支还是右支了。正确的做法是每个点都检查左支和右支。同时发现就返回当前点,否则继续深入搜索发现的那支。

这么做比较麻烦,要重复检索,属于top-down;所而用bottom-up就可以避免重复。

bottom-up就是post-order traversal,先遍历,再操作。根据返还的情况把结果传上去。

Time : O(n)
Space: O(n) ...算上递归的stack..

public class Solution {
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == q || root == p) return root;
        
        TreeNode leftRes = lowestCommonAncestor(root.left, p, q);
        TreeNode rightRes = lowestCommonAncestor(root.right, p, q);
        
        if (leftRes != null && rightRes != null) {
            return root;
        } else {
            return leftRes == null ? rightRes : leftRes;
        }
    }
}

Iteratively

第二种方法。

这种做法比较关键,1P3A上看到有类似的题,要求iteratively. 先从这个练手开始,具体做法哪来的忘了。

主要思路是通过in-order traversal先走一遍,这样遍历的顺序正好是BST的顺序,我们可以把遍历的顺序和NODE进行映射,通过map.

这样Binary Tree变成了BST,然后按照BST的方法来做就行了。

Time : O(n)建map + O(n)查询
Space :O(n) stack + O(n) map

public class Solution {
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == q || root == p) return root;
        
        Map<TreeNode, Integer> map = new HashMap<>();
        
        TreeNode temp = root;
        Stack<TreeNode> stk = new Stack<>();
        int i = 0;
        while (!stk.isEmpty() || temp != null) {
            while (temp != null) {
                stk.push(temp);
                temp = temp.left;
            }
            
            temp = stk.pop();
            map.put(temp, i ++);
            temp = temp.right;
        }
        
        
        // same as LCA with BST.
        temp = root;
        while (temp != null) {
            if (map.get(q) < map.get(temp) && map.get(p) < map.get(temp)) {
                temp = temp.left;
            } else if (map.get(q) > map.get(temp) && map.get(p) > map.get(temp)) {
                temp = temp.right;
            } else {
                return temp;
            }
        }
        
        return temp;
    }
}

通过in-order traversal给binary tree变BST的方式很奇特,不知道哪里还能用到。

原文地址:https://www.cnblogs.com/reboot329/p/6096321.html