Skip to content

Commit 2313092

Browse files
committed
Added question 236.
1 parent 3a643ff commit 2313092

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# 236. Lowest Common Ancestor of a Binary Tree
2+
3+
## Recursive Solution
4+
5+
- Runtime: O(N)
6+
- Space: O(H)
7+
- N = Number of nodes in tree
8+
- H = Height of tree
9+
10+
From the perspective of a root node, there are only three options to consider.
11+
- The LCA exists on the left sub-tree.
12+
- The LCA exists on the right sub-tree.
13+
- The LCA is the root node.
14+
15+
To figure out if an LCA exists would mean we need to find p and q in either sub-tree.
16+
If either are found, we have to let the parent know of their existence.
17+
18+
The other question is when to evaluate these conditions.
19+
We generally don't want to traverse a sub-tree if the LCA is already found, so if the recursion function returns the LCA, we should instead return it back up the tree.
20+
Secondly, if LCA has not been found from either side, we need to know if either p or q were found.
21+
So a number would be returned to the parent node.
22+
With this number, we can check if our root is p or q and add it with the returned number found.
23+
If the number happens to be 2, we found the LCA.
24+
In summary, we need a post-order traversal recursion call.
25+
26+
The worst case is that we have to traverse the entire tree to find p and q. However, we will never need more than height of the tree O(H) space to find p or q.
27+
28+
```
29+
from collections import namedtuple
30+
31+
LCA = namedtuple('LCA', ['n_found', 'lca'])
32+
33+
class Solution:
34+
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
35+
36+
def LCA_helper(root):
37+
if root is None:
38+
return LCA(n_found=0, lca=None)
39+
left = LCA_helper(root.left)
40+
if left.n_found == 2:
41+
return left
42+
right = LCA_helper(root.right)
43+
if right.n_found == 2:
44+
return right
45+
n_found = left.n_found + right.n_found + (1 if root is p or root is q else 0)
46+
return LCA(n_found=n_found, lca=root if n_found == 2 else None)
47+
48+
return LCA_helper(root).lca
49+
```

0 commit comments

Comments
 (0)