Lowest Common Ancestor of a Binary Tree

原题: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/

题意: 给定一棵二叉树,寻找其中两个给定节点的最近公共祖先(LCA)。

根据维基百科对LCA的定义:“节点v与w的最近公共祖先是树T上同时拥有v与w作为后继的最低节点(我们允许将一个节点当做其本身的后继)”

例子: 

 给定二叉树:
       _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4
节点5和1的最近公共祖先(LCA)是3,节点5和4的LCA是5,因为根据LCA的定义,一个节点可以是其本身的后继。

标签: lca、祖先、后继、lowest、ancestor、面试
猜你感兴趣的圈子:
LeetCode交流圈
  • Bingo
    2017-08-18 17:07:36 1楼#1层
    Python:迭代法
    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution:
        # @param {TreeNode} root
        # @param {TreeNode} p
        # @param {TreeNode} q
        # @return {TreeNode}
        def lowestCommonAncestor(self, root, p, q):
            pathP, pathQ = self.findPath(root, p), self.findPath(root, q)
            lenP, lenQ = len(pathP), len(pathQ)
            ans, x = None, 0
            while x < min(lenP, lenQ) and pathP[x] == pathQ[x]:
                ans, x = pathP[x], x + 1
            return ans
            
        def findPath(self, root, target):
            stack = []
            lastVisit = None
            while stack or root:
                if root:
                    stack.append(root)
                    root = root.left
                else:
                    peek = stack[-1]
                    if peek.right and lastVisit != peek.right:
                        root = peek.right
                    else:
                        if peek == target:
                            return stack
                        lastVisit = stack.pop()
                        root = None
            return stack
  • Bingo
    2017-08-18 17:08:17 2楼#1层
    Java:迭代法
    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;
        }
    }
  • Bingo
    2017-08-18 17:09:23 3楼#1层
    Python:递归法
    def lowestCommonAncestor(self, root, p, q):
        if root in (None, p, q): return root
        left, right = (self.lowestCommonAncestor(kid, p, q)
                       for kid in (root.left, root.right))
        return root if left and right else left or right
  • Bingo
    2017-08-18 17:09:52 4楼#1层
    Ruby:递归法
    def lowest_common_ancestor(root, p, q)
        return root if [nil, p, q].index root
        left = lowest_common_ancestor(root.left, p, q)
        right = lowest_common_ancestor(root.right, p, q)
        left && right ? root : left || right
    end
  • Bingo
    2017-08-18 17:10:10 5楼#1层
    Java:递归法
    public TreeNode lowestCommonAncestor(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);
        return left == null ? right : right == null ? left : root;
    }
  • Bingo
    2017-08-18 17:10:50 6楼#1层
    C++:递归法
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (!root || root == p || root == q) return root;
        TreeNode* left = lowestCommonAncestor(root->left, p, q);
        TreeNode* right = lowestCommonAncestor(root->right, p, q);
        return !left ? right : !right ? left : root;
    }
  • Bingo
    2017-08-18 17:11:42 7楼#1层
    C++:迭代法
    class Solution {
        struct Frame {
            TreeNode* node;
            Frame* parent;
            vector<TreeNode*> subs;
        };
    public:
        TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
            Frame answer;
            stack<Frame> stack;
            stack.push({root, &answer});
            while (stack.size()) {
                Frame *top = &stack.top(), *parent = top->parent;
                TreeNode *node = top->node;
                if (!node || node == p || node == q) {
                    parent->subs.push_back(node);
                    stack.pop();
                } else if (top->subs.empty()) {
                    stack.push({node->right, top});
                    stack.push({node->left, top});
                } else {
                    TreeNode *left = top->subs[0], *right = top->subs[1];
                    parent->subs.push_back(!left ? right : !right ? left : node);
                    stack.pop();
                }
            }
            return answer.subs[0];
        }
    };
  • 回复
隐藏