Given the root node of a binary tree root
and two values in the tree p
and q
, return the value of their lowest common ancestor. All the values in the tree are unique.
Example:
0. Problem
The LCA is the node where p
is to the left and q
is to the right, or vice versa:
The LCA can also equal p
and have q
in one of its subtrees, or vice versa:
Putting these together, here's the equation for the LCA. The function hasPorQ
computes whether p or q shows up in a subtree.
1. Recursion
It's not obvious how to find a recursion for LCA, but we definitely need to compute hasPorQ
at each node in the tree, so we might as well find a recursion for that. Here's the recursion for hasPorQ:
Notice that this recursion already computes everything we need in order to compute the LCA. So a clever idea is to "hijack" it, and use it to compute the LCA. We can do this by just copying the above recursion and sticking in a line of code:
2. Base case
The base case is:
3. Code
We just have to combine the recursion and base case. We'll keep a global variable "LCA", and update it when we see a node that could be the LCA. Here's the code:
Note that hasPorQ
runs on low nodes first and high nodes last, because it gets set after hasPorQ
was already called on the node's children. This is important, because we need to return the highest node that satisfies this equation.
Time Complexity O(n). We visit each node once and do an O(1) operation on it.
Space Complexity O(n). The Call Stack grows up to size n.
TreeNode.of
function can be used to create an entire binary tree using 1 line of code. The input is a BFS traversal of the tree including nulls, and the output is the root node of the tree.TreeNode.of([1, None, 2, None, 3])
ListNode.of
function lets you create an entire Linked List using 1 line of code. The input is an array, and the output is the head of the Linked List.ListNode.of([1, 2, 3])
ListNode.of([1, 2, 3], 1)
GraphNode.of
function lets you create an entire Graph using 1 line of code. The input is an Adjacency Matrix, and the output is the first node in the matrix.GraphNode.of([ ['A', 1, 2], ['B', 2], ['C', 0] ])
[['__init__', 15], ['add', 16], ['get']]
c = MyClass(15) c.add(16) c.get()
TreeNode.of
function can be used to create an entire binary tree using 1 line of code. The input is a BFS traversal of the tree including nulls, and the output is the root node of the tree.TreeNode.of([1, None, 2, None, 3])
ListNode.of
function lets you create an entire Linked List using 1 line of code. The input is an array, and the output is the head of the Linked List.ListNode.of([1, 2, 3])
ListNode.of([1, 2, 3], 1)
GraphNode.of
function lets you create an entire Graph using 1 line of code. The input is an Adjacency Matrix, and the output is the first node in the matrix.GraphNode.of([ ['A', 1, 2], ['B', 2], ['C', 0] ])
[['__init__', 15], ['add', 16], ['get']]
c = MyClass(15) c.add(16) c.get()