LeetCode NoteBook

Write down temporary 'wisdom' ..

Q99. Recover Binary Search Tree

You are given the root of a binary search tree (BST), where exactly two nodes of the tree were swapped by mistake. Recover the tree without changing its structure.

Follow up: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

 

Example 1:


Input: root = [1,3,null,null,2]
Output: [3,1,null,null,2]
Explanation: 3 cannot be a left child of 1 because 3 > 1. Swapping 1 and 3 makes the BST valid.
Example 2:


Input: root = [3,1,4,null,null,2]
Output: [2,1,4,null,null,3]
Explanation: 2 cannot be in the right subtree of 3 because 2 < 3. Swapping 2 and 3 makes the BST valid.
 

Constraints:

The number of nodes in the tree is in the range [2, 1000].
-231 <= Node.val <= 231 - 1

Here I focus on the solution with $O(N)$ space complexity, which definitely falls into the category of “need to know”.

The whole point is about performing the in-order traverse of the BST. If the BST is valid, the in-order traverse will result in an ascending order sequence. Whereas, if the BST is not valid, the resulting sequence won’t be ascending and as stated in the question, it should be fixed by a simple swap. For instance, if we have 0, 1, 4, 3, 2, 5, 6, we can easily see that 4 and 2 are swapped. This means that suppose we have the sequence, we could identify the pair to swap by extracting all the pairs with wrong order and extract the first and the last number of these pairs.

So, all the point of this question is to have in-order traverse in mind clearly. To have it briefly reviewed, the in-order traverse procedure is:

  • Maintain a stack of node to visit.
  • At a current node, push itself to the to-visit stack and go to its left child until there exists no more left child.
  • Go to the top of the stack, visit that node and set its right child as current node.

The Python submission is.

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def recoverTree(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        # do in order traverse
        left_most = TreeNode(val=-float('inf'))
        to_visit = []
        prev = left_most
        mistake = []
        curr = root
        while curr is not None or len(to_visit) > 0:
            while curr is not None:
                to_visit.append(curr)
                curr = curr.left
            node = to_visit.pop()
            # print(node.val)
            if node.val < prev.val:
                mistake.append(prev)
                mistake.append(node)
            prev = node
            curr = node.right
        tmp = mistake[0].val
        mistake[0].val = mistake[-1].val
        mistake[-1].val = tmp
        return root

NOTE: the $O(1)$ space complexity solution is about improving the in-order traverse. This question is related to Q94. Binary Tree Inorder Traversal which is discussed in this post.

Last updated on 31 Oct 2020
Published on 31 Oct 2020
Edit on GitHub