# 236. Lowest Common Ancestor of a Binary Tree

**<font color=red>难度: Medium</font>**

## 刷题内容

> 原题连接

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

> 内容描述

```
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 p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given the following binary tree:  root = [3,5,1,6,2,0,8,null,null,7,4]

        _______3______
       /              \
    ___5__          ___1__
   /      \        /      \
   6      _2       0       8
         /  \
         7   4
Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of of nodes 5 and 1 is 3.
Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself
             according to the LCA definition.
Note:

All of the nodes' values will be unique.
p and q are different and both values will exist in the binary tree.
```

## 解题方案

> 思路 1
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******


1. Find path from root to n1 and store it in a vector or array.
2. Find path from root to n2 and store it in another vector or array.
3. Traverse both paths till the values in arrays are same. Return the common element just before the mismatch.

时间复杂度worst case 是O(N)，空间is the same

beats 39.24%

```python
class Solution(object):
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        def findPath(root, path, node):
            if not root:
                return False
            path.append(root)
            if root == node:
                return True
            if (root.left and findPath(root.left, path, node)) or \
                (root.right and findPath(root.right, path, node)):
                return True
            path.pop()
            return False
        
        path_p, path_q = [], []
        if not findPath(root, path_p, p) or not findPath(root, path_q, q):
            return -1
        i = 0
        while i < len(path_p) and i < len(path_q):
            if path_p[i] != path_q[i]:
                break
            i += 1
        return path_p[i-1]
```

> 思路 2
******- 时间复杂度: O(N)******- 空间复杂度: O(N)******


看代码才是最容易懂的，直接看吧

每个点都要访问一次，时间O(N)

是DFS且不属于尾递归优化的情况，所以空间复杂度为dfs的深度，题目虽然是二叉树但是不是完全二叉树，所以最坏情况空间复杂度为O(N)

```python
class Solution:
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if left and right:
            return root
        return left or right
```



```if left and right```可以翻译成人话一下，其实它就是说p和q一人在root的一边，直接在这个check下面再加一个check发现就是一样的



也就是替换成

```
        if left and right:
            if (p.val == left.val and q.val == right.val) or (p.val == right.val and q.val == left.val):
                return root
```

发现也可以AC
