leetcode 236. Lowest Common Ancestor of a Binary Tree

来源:互联网 发布:吉田のしる知る 番号 编辑:程序博客网 时间:2024/06/06 17:55

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.

题意是找到两个结点中最低的共同父结点。

注意这个测试用例:找到3和2的LCA,答案是3。

           3
          /  \
        1    4
          \
           2

我的思路是:找到到达目标结点的路径,然后从后往前检查两个路径中相同的结点。

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {List<TreeNode> pPath=new ArrayList<TreeNode>();List<TreeNode> qPath=new ArrayList<TreeNode>();boolean[] isFind=new boolean[1];isFind[0]=false;findPath(root, p, pPath, isFind);isFind[0]=false;findPath(root, q, qPath, isFind);for(int i=pPath.size()-1;i>=0;i--){for(int j=qPath.size()-1;j>=0;j--){if(pPath.get(i)==qPath.get(j)){return pPath.get(i);}}}return null;}public void findPath(TreeNode node, TreeNode target,List<TreeNode> path,boolean[] isFind){if(node==null||isFind[0]==true){return;}path.add(node);if(node==target){isFind[0]=true;return;}findPath(node.left, target, path, isFind);if(isFind[0]==false){findPath(node.right, target, path, isFind);}if(isFind[0]==false){path.remove(node);}}

大神思路有点跟我类似:

要想找到LCA,需要追溯 p 和 q 的祖先。首先用一个map来记录所有结点和他们的父节点:map存储<node,node.parent>。然后,建立 p 的所有祖先集合。然后再追溯  q 的祖先,其中第一个出现在 p 的祖先集合 中的结点,就是我们的答案。

public class Solution {    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {        Map<TreeNode, TreeNode> parent = new HashMap<>();        Deque<TreeNode> stack = new ArrayDeque<>();        parent.put(root, null);        stack.push(root);        while (!parent.containsKey(p) || !parent.containsKey(q)) {            TreeNode node = stack.pop();            if (node.left != null) {                parent.put(node.left, node);                stack.push(node.left);            }            if (node.right != null) {                parent.put(node.right, node);                stack.push(node.right);            }        }        Set<TreeNode> ancestors = new HashSet<>();        while (p != null) {            ancestors.add(p);            p = parent.get(p);        }        while (!ancestors.contains(q))            q = parent.get(q);        return q;    }}

另外,还有大神用了很简洁的递归方法,这个思路很不错:
如果当前结点的左右子树找到了p和q(如左子树找到p 右子树找到q,或者左子树找到q 右子树找到p),那么当前结点就是它们的LCA,返回当前结点。如果只在左右子树的其中一个找到了p和q(如左子树包含了p和q,或者右子树包含了p和q),那么结果就是该子树递归的LCA。

比如: 5
           /  \
         3    9
        /  \
      1    4

求1和4的LCA。在root=3时,return 3,然后在root=5时,left=3,right=null,因此 return 3。

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);    return left != null && right != null ? root : left == null ? right : left; }


阅读全文
0 0
原创粉丝点击