Skip to content

Commit cc73dd7

Browse files
committed
236_Lowest_Common_Ancestor_of_a_Binary_Tree
1 parent 02b81c3 commit cc73dd7

3 files changed

+150
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Also, there are open source implementations for basic data structs and algorithm
8787
| 220 | [Contains Duplicate III](https://leetcode.com/problems/contains-duplicate-iii/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/220_Contains_Duplicate_III.py) | 1. Sort and binary Search <br>2. Bucket sort |
8888
| 221 | [Maximal Square](https://leetcode.com/problems/maximal-square/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/221_Maximal_Square.py) | 1. Brute force<br> 2. dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1, O(mn) and O(mn)<br>3. dp[j] = min([j], dp[j-1], prev) + 1, O(mn) and O(n)|
8989
| 228 | [Summary Ranges](https://leetcode.com/problems/summary-ranges/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/228_Summary_Ranges.py) | Detect start and jump, O(n) and O(1) |
90+
| 236 | [Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/236_Lowest_Common_Ancestor_of_a_Binary_Tree.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/236_Lowest_Common_Ancestor_of_a_Binary_Tree.java) | 1. Recursive check left, val and right, LCA is the split paths in tree, O(n) and O(n)<br>2. Store parents during traversing tree, reverse check their lowest common parent, O(n) and O(n) |
9091
| 238 | [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/238_Product_of_Array_Except_Self.py) [Java](https://github.com/qiyuangong/leetcode/blob/master/java/238_Product_of_Array_Except_Self.java) | The ans is [0,i -1] * [i+1, len- 1]. We can twice for left and right (reverse), O(n) and O(n) |
9192
| 243 | [Shortest Word Distance](https://leetcode.com/problems/shortest-word-distance/) | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/243_Shortest_Word_Distance.py) | Update index1 and index2, and check distance, O(n) and O(1) |
9293
| 246 | [Strobogrammatic Number](https://leetcode.com/problems/strobogrammatic-number/) &hearts; | [Python](https://github.com/qiyuangong/leetcode/blob/master/python/246_Strobogrammatic_Number.py) | Hash table and reverse string, O(n) and O(n) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
class Solution {
2+
3+
private TreeNode ans;
4+
5+
public Solution() {
6+
// Variable to store LCA node.
7+
this.ans = null;
8+
}
9+
10+
private boolean recurseTree(TreeNode currentNode, TreeNode p, TreeNode q) {
11+
12+
// If reached the end of a branch, return false.
13+
if (currentNode == null) {
14+
return false;
15+
}
16+
17+
// Left Recursion. If left recursion returns true, set left = 1 else 0
18+
int left = this.recurseTree(currentNode.left, p, q) ? 1 : 0;
19+
20+
// Right Recursion
21+
int right = this.recurseTree(currentNode.right, p, q) ? 1 : 0;
22+
23+
// If the current node is one of p or q
24+
int mid = (currentNode == p || currentNode == q) ? 1 : 0;
25+
26+
27+
// If any two of the flags left, right or mid become True
28+
if (mid + left + right >= 2) {
29+
this.ans = currentNode;
30+
}
31+
32+
// Return true if any one of the three bool values is True.
33+
return (mid + left + right > 0);
34+
}
35+
36+
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
37+
// Traverse the tree
38+
this.recurseTree(root, p, q);
39+
return this.ans;
40+
}
41+
42+
/*public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
43+
// Stack for tree traversal
44+
Deque<TreeNode> stack = new ArrayDeque<>();
45+
46+
// HashMap for parent pointers
47+
Map<TreeNode, TreeNode> parent = new HashMap<>();
48+
49+
parent.put(root, null);
50+
stack.push(root);
51+
52+
// Iterate until we find both the nodes p and q
53+
while (!parent.containsKey(p) || !parent.containsKey(q)) {
54+
55+
TreeNode node = stack.pop();
56+
57+
// While traversing the tree, keep saving the parent pointers.
58+
if (node.left != null) {
59+
parent.put(node.left, node);
60+
stack.push(node.left);
61+
}
62+
if (node.right != null) {
63+
parent.put(node.right, node);
64+
stack.push(node.right);
65+
}
66+
}
67+
68+
// Ancestors set() for node p.
69+
Set<TreeNode> ancestors = new HashSet<>();
70+
71+
// Process all ancestors for node p using parent pointers.
72+
while (p != null) {
73+
ancestors.add(p);
74+
p = parent.get(p);
75+
}
76+
77+
// The first ancestor of q which appears in
78+
// p's ancestor set() is their lowest common ancestor.
79+
while (!ancestors.contains(q))
80+
q = parent.get(q);
81+
return q;
82+
}*/
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Definition for a binary tree node.
2+
# class TreeNode(object):
3+
# def __init__(self, x):
4+
# self.val = x
5+
# self.left = None
6+
# self.right = None
7+
8+
class Solution(object):
9+
# def lowestCommonAncestor(self, root, p, q):
10+
# """
11+
# :type root: TreeNode
12+
# :type p: TreeNode
13+
# :type q: TreeNode
14+
# :rtype: TreeNode
15+
# """
16+
# self.ans = None
17+
18+
# def lowestCommonAncestorHelper(node):
19+
# if not node:
20+
# return False
21+
# left = lowestCommonAncestorHelper(node.left)
22+
# right = lowestCommonAncestorHelper(node.right)
23+
# mid = node == p or node == q
24+
# if mid + left + right >= 2:
25+
# self.ans = node
26+
# return mid or left or right
27+
# lowestCommonAncestorHelper(root)
28+
# return self.ans
29+
30+
def lowestCommonAncestor(self, root, p, q):
31+
"""
32+
:type root: TreeNode
33+
:type p: TreeNode
34+
:type q: TreeNode
35+
:rtype: TreeNode
36+
"""
37+
# Stack for tree traversal
38+
stack = [root]
39+
# Dictionary for parent pointers
40+
parent = {root: None}
41+
# Iterate until we find both the nodes p and q
42+
while p not in parent or q not in parent:
43+
44+
node = stack.pop()
45+
46+
# While traversing the tree, keep saving the parent pointers.
47+
if node.left:
48+
parent[node.left] = node
49+
stack.append(node.left)
50+
if node.right:
51+
parent[node.right] = node
52+
stack.append(node.right)
53+
54+
# Ancestors set() for node p.
55+
ancestors = set()
56+
57+
# Process all ancestors for node p using parent pointers.
58+
while p:
59+
ancestors.add(p)
60+
p = parent[p]
61+
62+
# The first ancestor of q which appears in
63+
# p's ancestor set() is their lowest common ancestor.
64+
while q not in ancestors:
65+
q = parent[q]
66+
return q

0 commit comments

Comments
 (0)