Find the Meeting Point of Two Keys in a Search Tree
Solve this ProblemYou are given the root of a binary search tree with distinct values and two values p and q that both appear in the tree. Return the value of the lowest node that has both the p-node and the q-node in its subtree; a node counts as being inside its own subtree, so if one of the two nodes is an ancestor of the other, that ancestor is the answer.
The method for general binary trees works here too, but the ordering of a search tree lets you find the answer with a single downward walk, since the keys tell you which side each of them is on.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
2 ≤ number of nodes ≤ 100; all node values are distinct, 0 ≤ node.val ≤ 1000 - ◆
The tree is a binary search tree (left subtree smaller, right subtree larger at every node), given by its root node - ◆
p and q are values that both exist in the tree (they may be equal to each other) - ◆
Return the value of the lowest node that has both the p-node and the q-node in its subtree (a node counts as being in its own subtree, so if one is an ancestor of the other, the answer is that ancestor)
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Treat It as an Ordinary Tree and Search Both Sides
BruteIgnore the ordering and use the general method: a helper returns a node as soon as it is p or q, and otherwise asks both subtrees. If both report something, this node is the meeting point; if only one does, pass its answer up. This is correct for any binary tree but it may visit every node — O(n) time, O(h) recursion space — and it never uses the search-tree property.
O(n)O(h)1class Solution {
2 public int lowestCommonInBst(TreeNode root, int p, int q) {
3 return find(root, p, q).val;
4 }
5
6 private TreeNode find(TreeNode node, int p, int q) {
7 if (node == null || node.val == p || node.val == q) return node;
8 TreeNode left = find(node.left, p, q);
9 TreeNode right = find(node.right, p, q);
10 if (left != null && right != null) return node;
11 return left != null ? left : right;
12 }
13}Optimal — Walk Down Until the Two Keys Go Different Ways
OptimalIn a search tree the ordering tells where each key is. Starting at the root: if BOTH keys are smaller than the current node they are both in the left subtree, so move left; if BOTH are larger, move right. The first node at which they are NOT on the same side — one is smaller and the other larger, or one of them equals the node — is where their paths separate, and that node is the lowest one above both. It is found with a single downward walk: O(h) time and O(1) space.
O(h)O(1)1class Solution {
2 public int lowestCommonInBst(TreeNode root, int p, int q) {
3 TreeNode cur = root;
4 while (cur != null) {
5 if (p < cur.val && q < cur.val) {
6 cur = cur.left;
7 } else if (p > cur.val && q > cur.val) {
8 cur = cur.right;
9 } else {
10 return cur.val;
11 }
12 }
13 return -1;
14 }
15}