BST Inorder Successor in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to find the next bigger value in a Binary Search Tree (BST).
How does the time needed grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
function inorderSuccessor(root: TreeNode | null, p: TreeNode | null): TreeNode | null {
let successor: TreeNode | null = null;
while (root) {
if (p!.val < root.val) {
successor = root;
root = root.left;
} else {
root = root.right;
}
}
return successor;
}
This code finds the next bigger node after a given node p in a BST by walking down the tree.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves down the tree nodes.
- How many times: At most once per level of the tree, until it reaches a leaf or finds the successor.
Each step moves one level down the tree, so the number of steps depends on the tree height.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 4 steps (if tree is balanced) |
| 100 | Up to 7 steps |
| 1000 | Up to 10 steps |
Pattern observation: The steps grow slowly as the tree grows, roughly with the tree height.
Time Complexity: O(h)
This means the time grows with the height of the tree, which is the number of levels from root to leaf.
[X] Wrong: "Finding the successor always takes time proportional to the total number of nodes."
[OK] Correct: The search only moves down one path, not the whole tree, so it depends on tree height, not total nodes.
Understanding this helps you explain how tree shape affects search speed, a key skill for working with trees in real problems.
"What if the BST is not balanced but skewed like a linked list? How would the time complexity change?"
Practice
Solution
Step 1: Understand inorder traversal order
Inorder traversal visits nodes in ascending order of their keys in a BST.Step 2: Define inorder successor
The inorder successor of a node is the next node visited after it in inorder traversal, which is the smallest node with a key greater than the current node.Final Answer:
The node with the smallest key greater than the given node's key -> Option AQuick Check:
Inorder successor = next bigger node [OK]
- Confusing successor with predecessor
- Thinking successor is always right child
- Assuming successor is parent node
Solution
Step 1: Analyze parameters needed
To find inorder successor, we need the BST root and the target node p.Step 2: Analyze return type
The function returns the successor node or null if none exists.Final Answer:
function inorderSuccessor(root: TreeNode | null, p: TreeNode): TreeNode | null -> Option AQuick Check:
Correct params and return type [OK]
- Missing root parameter
- Wrong return type (void or number)
- Not allowing null root
6
/ \
2 8
/ \ \
0 4 9
/ \
3 5
Solution
Step 1: Locate node 5 and check right subtree
Node 5 has no right child, so successor is one of its ancestors.Step 2: Find lowest ancestor whose left child is ancestor of node 5
Node 6 is the first ancestor where node 5 is in left subtree, so successor is node 6.Final Answer:
Node with value 6 -> Option BQuick Check:
Successor of 5 is 6 [OK]
- Choosing right child of root instead of ancestor
- Picking node 8 which is too big
- Confusing predecessor with successor
function inorderSuccessor(root: TreeNode | null, p: TreeNode): TreeNode | null {
let successor: TreeNode | null = null;
while (root) {
if (p.val < root.val) {
successor = root;
root = root.left;
} else {
if (p.val === root.val) {
return successor;
}
root = root.right;
}
}
return successor;
}
What is the bug in this code?Solution
Step 1: Understand code logic
The code moves down the tree to find the smallest node greater than p.val, updating successor accordingly.Step 2: Identify missing case
If p has a right subtree, the successor is the leftmost node in that subtree, but this code ignores that and only searches from root.Final Answer:
It does not handle the case when node p has a right subtree -> Option CQuick Check:
Right subtree check missing [OK]
- Ignoring right subtree of p
- Assuming successor always in ancestors
- Confusing successor with predecessor
Solution
Step 1: Check if p has right subtree
If p has a right child, the inorder successor is the smallest node in that right subtree.Step 2: Find leftmost node in right subtree
Traverse left children starting from p's right child until no more left child exists.Final Answer:
Return the leftmost node in p's right subtree -> Option DQuick Check:
Successor in right subtree's leftmost node [OK]
- Returning parent instead of leftmost right subtree node
- Returning rightmost left subtree node
- Returning root regardless of p
Ready to prove it?
Pass the test and this pattern moves unknown
