Recover Binary Search Tree

To solve this coding challenge, we need to recover a Binary Search Tree (BST) in which exactly two nodes have been swapped by mistake, without altering the structure of the tree. The constraints require us to achieve this recovery in an efficient manner, with the follow-up hint suggesting an O(1) space solution.

Explanation

The key properties of a BST we need to rely on are:
  1. The left subtree of a node contains only nodes with values less than the node's value.
  2. The right subtree of a node contains only nodes with values greater than the node's value.
  3. An in-order traversal (left-root-right) of the BST should produce a sorted sequence of values.
  4. Given this, our approach will be based on identifying the two nodes that have been swapped by looking for the anomalies in the in-order traversal of the tree. Specifically, we expect to see exactly two out-of-order pairs of consecutive nodes in the in-order traversal. By swapping the values of these two nodes, we can restore the BST. We'll discuss the methodology step-by-step:
    Step-by-Step Explanation
  5. In-Order Traversal : Perform an in-order traversal of the BST to generate a sequence of node values.
  6. Identify Anomalies : Identify the two nodes where the BST property is violated.
  7. Swap Values : Swap the values of these two nodes to correct the BST.
  8. Detailed Steps in Pseudocode
  9. Utility Definitions :
    • Define the data structure for the tree nodes.
    • Define placeholder variables to hold the swapped nodes.
  10. In-Order Traversal :
    • Traverse the tree using in-order traversal while tracking the previous node.
    • Identify the two out-of-order nodes during traversal.
    • Use a stack to implement the iterative in-order traversal approach.
  11. Node Value Swap :
    • Once the two nodes are identified, swap their values.
Detailed Pseudocode with Comments
                                            
# Definition for a binary tree node
class TreeNode:
    # Initialization of TreeNode
    function __init__(value=0, left=None, right=None):
        this.value = value
        this.left = left
        this.right = right

# Function to recover the BST
function recoverTree(root):
    # Initialization of variables to track the swapped nodes
    firstSwappedNode = None
    secondSwappedNode = None
    previousNode = TreeNode(value=float('-inf'))  # Negative infinity as initial previous node
    stack = []  # Stack for iterative traversal

    # Perform in-order traversal
    while not stack.isEmpty() or root is not None:
        # Traverse to the leftmost node
        while root is not None:
            stack.append(root)
            root = root.left
        
        # Process the node
        root = stack.pop()
        
        # Identify out-of-order nodes
        if firstSwappedNode is None and previousNode.value >= root.value:
            firstSwappedNode = previousNode
        if firstSwappedNode is not None and previousNode.value >= root.value:
            secondSwappedNode = root
        
        # Update previous node and move to right subtree
        previousNode = root
        root = root.right
    
    # Swap values of the first and second swapped nodes
    if firstSwappedNode is not None and secondSwappedNode is not None:
        tempValue = firstSwappedNode.value
        firstSwappedNode.value = secondSwappedNode.value
        secondSwappedNode.value = tempValue

                                        
In this pseudocode, the emphasis is placed on utilizing an iterative in-order traversal with a stack to avoid recursive calls and maintain O(1) space complexity for the actual functional computations. The pseudo-comments inline explain the purpose of each block, and the variable names are chosen descriptively to reflect their purpose for clarity. This solution ensures that the structure of the BST remains unchanged while correcting the values of the swapped nodes, making the tree valid according to BST properties.