# 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);
    }
};