Intuition
In a BST you don't need to search both sides: if both targets are smaller than the current node, the LCA is left; both bigger, it's right. The first node between them (inclusive) is the split point — and the LCA.
In a BST the LCA is simply the first node whose value falls between the two targets — because that's exactly where their search paths diverge. No recursion into both subtrees, no bookkeeping: one walk, one comparison per level. Compare this with the general binary-tree LCA, which must explore both sides precisely because it has no ordering to exploit.
Approach
Walk, don't recurse everywhere
From the root: both p,q < node → left. Both > node → right. Otherwise node splits them → answer.
Why the split is the LCA
Any deeper node loses one of the targets to the other side — the split point is the last common node on both search paths.
Iterative one-liner walk
No stack, no parent pointers, O(h).
Solution & live demo
Common pitfalls
Using the general binary-tree algorithm
left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) if left and right: return root
if node.val < lo: node = node.right elif node.val > hi: node = node.left else: return node
That works but visits every node, O(n), and ignores the ordering that makes this problem Easy rather than Medium. The BST tells you which way both targets lie, so only one path is ever walked.
Assuming p is smaller than q
if node.val < p.val: node = node.right elif node.val > q.val: node = node.left
lo, hi = sorted((p.val, q.val))
The problem doesn't promise any order between the two nodes. If q is the smaller one, both comparisons can fail simultaneously and the walk returns the wrong node. Normalising to lo/hi removes the assumption.
Excluding the targets themselves
if lo < node.val < hi: return node
else: return node # lo <= node.val <= hi
A node is allowed to be its own descendant's ancestor, so when node.val equals one of the targets that node is the LCA. Strict comparisons walk straight past it.
Edge cases
The walk stops at that target (it's not strictly less/greater on one side) — correct.
O(n) walk but same logic.