↓Skip to main content
  1. LeetCode/

LeetCode 235: Lowest Common Ancestor of a Binary Search Tree

·2 mins· ·
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-08-22

  • Submissions: Runtime Error → Accepted ×2 → Wrong Answer → Runtime Error → Accepted → Runtime Error → Wrong Answer → Runtime Error → Accepted → Runtime Error → Accepted

Approach
#

Use the BST ordering instead of searching the whole tree (Tree Template 4):

  • Both p and q smaller: the LCA is in the left subtree.
  • Both larger: in the right subtree.
  • Otherwise they split, or one is the current node: the current node is the LCA.

My Attempts
#

The recursive version passed quickly. Converting it to iteration, attempt 1 forgot the while loop, stepping down once and returning nothing; attempt 2 was missing a colon. A November rewrite hit an undefined variable and a None attribute access.

Solution
#

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        node = root
        while True:
            if p.val < node.val and q.val < node.val:
                node = node.left
            elif p.val > node.val and q.val > node.val:
                node = node.right
            else:
                return node

Complexity
#

Time O(h), space O(1).

Mistakes to Avoid
#

  • When one node is the other’s ancestor, the answer is that ancestor; the conditions must allow equality.

Interview Explanation
#

From the root I go left while both are smaller and right while both are larger; otherwise they split here or one is this node, so I return it. Time O(h), space O(1).

Related

LeetCode 226: Invert Binary Tree
·1 min
LeetCode Easy Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 226 note: swap every node’s children, using a simultaneous assignment so the already-changed side is not reused
LeetCode 145: Binary Tree Postorder Traversal
·2 mins
LeetCode Easy Stack Tree Depth-First-Search Binary-Tree
LeetCode 145 note: iterative post-order pushes a node back with a visited flag on its first pop, then the right and left children; record it on the second pop
LeetCode 110: Balanced Binary Tree
·2 mins
LeetCode Easy Tree Depth-First-Search Binary-Tree
LeetCode 110 note: every node’s subtree heights must differ by at most 1; return heights in post-order and propagate -1 once unbalanced
LeetCode 111: Minimum Depth of Binary Tree
·1 min
LeetCode Easy Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 111 note: minimum depth must end at a leaf; with only one child, the empty side (depth 0) cannot count as the minimum
LeetCode 112: Path Sum
·1 min
LeetCode Easy Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 112 note: subtract each value from targetSum on the way down; it works if the remainder matches at a leaf
LeetCode 100: Same Tree
·1 min
LeetCode Easy Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 100 note: two empty trees are equal, one empty and one not differ, and otherwise compare values and recurse on both sides