# 99. Recover Binary Search Tree
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Example 1:
Input: [1,3,null,null,2]
1
/
3
\
2
Output: [3,1,null,null,2]
3
/
1
\
2
Example 2:
Input: [3,1,4,null,null,2]
3
/ \
1 4
/
2
Output: [2,1,4,null,null,3]
2
/ \
1 4
/
3
Follow up:
- A solution using O(n) space is pretty straight forward.
- Could you devise a constant space solution?
# Solution
Approach 1: run an inorder traversal, record all values then sort them -- compare with the unsorted. Time: O(NlogN) -- sorting. Space: O(N) -- the table, inorder values, and sorted inorder values.
Approach 2: do an inorder traversal; if we can find 1 single reversed value, then the swapped nodes are the reversed and the one right after it; if we can find 2 reversed values, then the first swapped is the node before the reversed, and the second swapped is the node reversed. Time: O(N), space: O(1).
Approach 3: run an inorder traversal and record the two swapped nodes.
# Code (Python)
Approach 1:
def recoverTree(self, root: 'TreeNode') -> 'None':
"""
Do not return anything, modify root in-place instead.
"""
val_to_node = {}
inorder = []
node = root
stack = []
while node:
stack.append(node)
node = node.left
while stack:
node = stack.pop()
val_to_node[node.val] = node
inorder.append(node.val)
if node.right:
node = node.right
while node:
stack.append(node)
node = node.left
inorder_sorted = list(sorted(inorder))
for i in range(len(inorder)):
if inorder[i] != inorder_sorted[i]:
node1, node2 = val_to_node[inorder[i]], val_to_node[inorder_sorted[i]]
node1.val, node2.val = node2.val, node1.val
break
Approach 2:
def recoverTree(self, root):
swapped = [None, None]
prev_node = None
# Morrison's inorder traversal with O(1) space
node = root
while node:
if not node.left:
# visit node
if prev_node and node.val < prev_node.val:
if not swapped[0]:
swapped[0] = prev_node
swapped[1] = node
else:
swapped[1] = node
prev_node = node
node = node.right
else:
predecessor = node.left
while predecessor.right and predecessor.right != node:
predecessor = predecessor.right
if not predecessor.right:
predecessor.right = node
node = node.left
else:
predecessor.right = None
# visit node
if prev_node and node.val < prev_node.val:
if not swapped[0]:
swapped[0] = prev_node
swapped[1] = node
else:
swapped[1] = node
prev_node = node
node = node.right
swapped[0].val, swapped[1].val = swapped[1].val, swapped[0].val
# Code (C++)
Approach 3:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode *prev;
TreeNode *swap1;
TreeNode *swap2;
void doRecoverTree(TreeNode* root) {
if (root == NULL)
return;
doRecoverTree(root->left);
if (prev && prev->val > root->val)
{
if (swap1 == NULL)
{
swap1 = prev;
swap2 = root;
}
else
{
swap2 = root;
}
}
prev = root;
doRecoverTree(root->right);
}
public:
void recoverTree(TreeNode* root) {
prev = NULL;
swap1 = NULL;
swap2 = NULL;
doRecoverTree(root);
if (swap1 && swap2)
std::swap(swap1->val, swap2->val);
}
};