Inorder Successor in BST

You are given the root of a binary search tree whose values are all distinct, and a node p that belongs to the tree. Return the in-order successor of p: the node holding the smallest value that is strictly greater than p.val. If p holds the largest value in the tree, return null.

The tree is given as a level-order array with null for missing children. In the test data, p is written as its value; the judge passes your function the actual node with that value. The judge checks the value of the node you return.

Example 1

Input: root = [20,10,30,5,15,25,40], p = 15 Output: 20 Why: 15 has no right child, so its successor is the nearest ancestor it sits to the left of: 20.

Example 2

Input: root = [8,4,12,2,6,10,14], p = 8 Output: 10 Why: 8 has a right subtree, and the smallest value in it is 10.

Example 3

Input: root = [3,1,5], p = 5 Output: null Why: 5 is the largest value in the tree, so there is no successor.

Constraints

  • 1 <= number of nodes <= 104
  • -105 <= Node.val <= 105
  • All values are unique, and p is a node of the tree.

Pattern Path · Binary Search Trees · problem 102 of 169

An in-order traversal lists a BST in sorted order, so you could traverse and return the node after p. Can you avoid visiting the whole tree?
You are looking for the smallest value greater than p.val. At any node, you know which side of it such values live on.
Walk down from the root. If the current node is greater than p, it is a candidate; a better (smaller) one can only be in its left subtree. Otherwise go right.
The last candidate you recorded before falling off the tree is the answer.
Target: O(h) time, O(1) extra space.

Start simple

Do a full in-order traversal into a list and return the element after p: O(n) time and O(n) space.

The key idea

The successor is the smallest value strictly greater than p.val, which is a search question, and a BST is built for search. Start at the root and keep one variable, successor.

  • If node.val > p.val, this node is greater than p, so it could be the answer. Remember it, then move left, because any better answer must be smaller than this node.
  • Otherwise the node (and its whole left subtree) is too small, so move right.

Each step discards one subtree that cannot contain a better answer, and every value greater than p.val that could beat the current candidate stays on the path. When the walk ends, successor holds the smallest value greater than p.val, or null if none exists.

This one loop covers both textbook cases: if p has a right subtree the walk ends at that subtree's leftmost node, and if not, the answer is the last ancestor where the path turned left. No parent pointers or extra memory are needed.

Complexity

  • Time: O(h)
  • Space: O(1)

Python

class Solution:
    def inorderSuccessor(self, root, p):
        successor = None
        node = root
        while node:
            if node.val > p.val:
                successor = node  # candidate; a smaller one can only be on the left
                node = node.left
            else:
                node = node.right
        return successor

JavaScript

var inorderSuccessor = function(root, p) {
  let successor = null;
  let node = root;
  while (node) {
    if (node.val > p.val) {
      successor = node; // candidate; a smaller one can only be on the left
      node = node.left;
    } else {
      node = node.right;
    }
  }
  return successor;
};

What the interviewer is checking

It checks whether you use the BST ordering to search in O(h) instead of falling back to a full traversal, and whether you handle the no-right-subtree case without parent pointers.

Mistakes to avoid

  • Only checking p.right: when p has no right subtree the successor is an ancestor, not null.
  • Using >= instead of >, which returns p itself.
  • Traversing the whole tree into a list, which is O(n) when O(h) is possible.
  • Forgetting to return null for the maximum node.

Follow-ups to expect

  • Find the in-order predecessor instead. (Mirror the comparisons.)
  • What if nodes had parent pointers and you had no root? (Climb until coming from a left child.)
  • Iterate the whole BST in order with O(h) memory. (Stack-based BST iterator.)

In real software

Ordered maps built on balanced trees (such as a tree map's higher-key lookup) answer "next key after this one" with exactly this walk, which is how range scans and cursor pagination step forward.

Practice next

Next Post Previous Post
No Comment
Add Comment
comment url