Lowest Common Ancestor of a Binary Tree

[Problem] 
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
Chinese translation:
給你一個binary tree(不是binary search tree喔!!),和其中的兩個點(並假設一定存於在樹中),請問他們的共同祖先中,最接近他們的是誰。

[Solution] 

Using DFS to find the path. Find the separate point of path.

Different from the previous question, this is a binary tree, not a binary search tree.
Which mean you cannot decide to go left/right by comparing the value.
You have to execute a DFS to find the path.

Now you know how to find the paths of q and p.
By compare the difference of these two paths, you will find the Lowest Common Ancestor.

class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { vector<TreeNode*> pathq; vector<TreeNode*> pathp; DFS(root, pathq, q->val); DFS(root, pathp, p->val); int i; for(i=0;i<pathq.size()-1 && i<pathp.size()-1 ;i++){ if(pathq[i+1]!=pathp[i+1]) break; } return pathq[i]; } bool DFS(TreeNode* root, vector<TreeNode*>& path, int target){ if(root==NULL) return false; path.push_back(root); if(root->val == target) return true; if(DFS(root->left , path, target)) return true; if(DFS(root->right, path, target)) return true; path.pop_back(); return false; } }; [Advance Solution] 
There is another smart solution in leetcode.
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/discuss/65226/My-Java-Solution-which-is-easy-to-understand
It is short but faster, because it only scan the tree for one time.

It use a recursive function which :
1.If p and q exist in left and right subtree separately--> return root, this is LCM
2.If one of one subtree have q or q, and another subtree doesn't have any --> return subtree's return value
3.If none of p and q exist in this tree, return NULL

TreeNode* lowestCommonAncestor2(TreeNode* root, TreeNode* p, TreeNode* q) { if (root==NULL || p == root || q == root) return root; TreeNode *left = lowestCommonAncestor(root->left, p, q); TreeNode *right = lowestCommonAncestor(root->right, p , q); if (left && right) return root; return left ? left : right; }