Home
DSA Patterns
Depth-First Search
Recover Binary Search Tree
Recover Binary Search Tree
Repair a binary search tree in which exactly two nodes' values were swapped, without changing its structure, by finding where the inorder sequence stops increasing.
Problem Understanding
Recover Binary Search Tree: the values of exactly two nodes of a binary search tree were swapped by mistake. Recover the tree without changing its structure.
Examples: [1,3,null,null,2] → [3,1,null,null,2]; [3,1,4,null,null,2] → [2,1,4,null,null,3].
The Intuition: A Sorted List With Two Elements Swapped
Read the tree in inorder, as in Binary Tree Inorder Traversal, and it becomes a sorted list with two entries swapped:
- Find the drops where a value is smaller than the previous one.
- First wrong value: the larger side of the first drop.
- Second wrong value: the smaller side of the last drop (the same drop if there is only one).
- Swap them back.
The increasing-inorder check is the same one Validate Binary Search Tree relies on.
Interactive Walkthrough
#n = INORDER POSITION · RED = OUT OF PLACE
INORDER SHOULD INCREASE
first
:
second
:
inorder so far
None yet
Walk the tree in inorder. In a valid BST every value is larger than the one before it; look for drops
Next
1 is the first value in inorder
root
Each visited node shows its inorder position. The previous node is outlined, suspects turn red when a drop exposes them, and they turn green once swapped. Try Far apart for the two-drop case.
Dry Run Table
Input: [3,1,4,null,null,2], inorder 1, 3, 2, 4.
| prev | node | Drop? | first | second |
|---|---|---|---|---|
| - | 1 | |||
| 1 | 3 | no | ||
| 3 | 2 | yes | 3 | 2 |
| 2 | 4 | no | 3 | 2 |
Swap 3 and 2. Answer: [2,1,4,null,null,3].
The Solution Template
One recursive inorder walk, then a swap.
Recover Binary Search Tree Code
1var recoverTree = function(root) {2 let prev = null, first = null, second = null;3 const inorder = (node) => {4 if (!node) return;5 inorder(node.left);6 if (prev && prev.val > node.val) {7 if (!first) first = prev;8 second = node;9 }10 prev = node;11 inorder(node.right);12 };13 inorder(root);14 [first.val, second.val] = [second.val, first.val];15};
Edge Cases & Common Mistakes
- Adjacent swap: only one drop; set
secondon every drop so it is still found. - Setting first on every drop: overwrites it with the wrong node in the two-drop case.
- Root involved: the method does not care where the nodes are.
- Comparing with parents only: a swap can break the BST order far from the parent link.
- Static state in C/Java: reset
prev,firstandsecondbefore each call.
Summary
Walk inorder tracking the previous node; at the first drop record the larger value's node, at every drop record the smaller value's node; swap the two values. O(n) time, O(h) space.
More practice: DSA interview questions with answers · patterns cheat sheet
