> For the complete documentation index, see [llms.txt](https://hao-fu-1.gitbook.io/oj/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hao-fu-1.gitbook.io/oj/binary_tree_and_divide_conquer/divide-and-concquer/lowest-common-ancestor-of-a-binary-tree.md).

# 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).”

## Thoughts

找二叉树上两个结点的最底层的共同祖先。分治思想：当前结点为lca和lca分别在左右子树，以及lca不在此子树上。让lca()遇到p/q时直接返回p/q，此时当左右都不为null时当前结点就是LCA，否则定有一个子树返回空。

## Code

```
/*
 * @lc app=leetcode id=236 lang=cpp
 *
 * [236] Lowest Common Ancestor of a Binary Tree
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == nullptr || root == p || root == q) return root;
        auto left = lowestCommonAncestor(root->left, p, q); 
        auto right = lowestCommonAncestor(root->right, p, q);
        if (left != nullptr && right != nullptr) return root;
        return left == nullptr ? right : left;
    }
};
// @lc code=end


```

```
class Solution {    
    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;
    }
}
```

## Analysis

只有一次分治，n个结点每个结点O(1)，总时间O(n).

## Ver.2

ans stack存储每个节点是否是p和q的ancestor，巧妙利用pre结点已经包含了两种backtracking的结果让它和当前结果做OR。由于pre还可能是上步push\_left(cur->right)中的cur，此时的cur一定是叶子，因此对push\_left后这个特殊pre做下清空。

```
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (p == q) return p;
        stack<TreeNode*> s;
        stack<pair<bool, bool>> ans;
        const auto push_left = [&](TreeNode *cur) {
            while (cur != NULL) {
                s.push(cur);
                if (cur == p) ans.push({true, false});
                else if (cur == q) ans.push({false, true});
                else ans.push({false, false});
                cur = cur->left;
            }
        };
        TreeNode *pre;
        pair<bool, bool> pre_a;
        push_left(root);
        while (!s.empty()) {
            const auto cur = s.top();
            auto &a = ans.top();
            a.first |= pre_a.first;
            a.second |= pre_a.second;
            if (a.first && a.second) return cur;
            if (cur->right != NULL && cur->right != pre) {
                push_left(cur->right);
                pre_a = {false, false};
                continue;
            }
            pre = cur;
            pre_a = a;
            s.pop();
            ans.pop();
        }
        
        return root;
    }
};
```
