You are given the root of a binary search tree (BST), where the values of exactly two nodes of the tree were swapped by mistake. Recover the tree without changing its structure.
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:
[2, 1000].-231 <= Node.val <= 231 - 1Follow up: A solution using
O(n) space is pretty straight-forward. Could you devise a constant O(1) space solution?Problem Overview: You are given the root of a Binary Search Tree where exactly two nodes were swapped by mistake. The structure of the tree is unchanged, but the BST property is violated. Your task is to recover the tree by swapping those two nodes back without changing the tree structure.
A valid binary search tree produces a strictly increasing sequence during an inorder traversal. When two nodes are swapped, this sorted order breaks at one or two positions. The key idea behind most solutions is to detect these violations during traversal and identify the two misplaced nodes.
Approach 1: In-Order Traversal with Additional Space (O(n) time, O(n) space)
This approach performs a standard inorder traversal and stores the visited node values in an array. Because inorder traversal of a BST should produce a sorted sequence, you can scan the array to find the two elements that violate the sorted order. Typically, the first violation marks the first misplaced node, and the second violation identifies the second node. After locating them, swap their values in the original tree.
The algorithm works in three phases: perform inorder traversal, detect the two incorrect values by comparing adjacent elements, then traverse the tree again to swap those values. The logic is straightforward and easy to reason about, making it a good starting point for understanding the problem. However, it requires extra memory proportional to the number of nodes because the entire traversal result is stored.
Approach 2: Morris Traversal for Constant Space Complexity (O(n) time, O(1) space)
This method removes the need for recursion or auxiliary arrays by using Morris traversal, a technique that temporarily modifies the tree to simulate depth-first search. Instead of using a stack, the algorithm creates temporary "threads" between nodes so you can return to a parent after finishing its left subtree.
While performing the inorder traversal, keep track of the previous visited node. Whenever prev.val > current.val, a BST violation occurs. The first violation identifies the first misplaced node, and the second violation identifies the second node. After completing the traversal, swap the values of these two nodes to restore the BST property.
Morris traversal maintains the inorder visiting order while using constant extra memory. The tree is restored to its original structure after traversal because temporary links are removed. This approach is considered optimal since it achieves O(n) time and O(1) auxiliary space.
Recommended for interviews: Interviewers usually expect the constant space solution. Starting with the simple inorder traversal approach demonstrates understanding of BST properties and debugging techniques. Following it with the Morris traversal optimization shows deeper knowledge of tree traversal algorithms and memory-efficient design. Being able to detect swapped nodes during a single traversal is the key insight tested in most interviews involving tree and BST problems.
This approach uses an additional list to store the nodes during an in-order traversal of the BST. The in-order traversal yields the values of the BST in a sorted manner for a correct BST configuration. If two nodes have been swapped, this sorted order will be violated in exactly two places. By storing all nodes during traversal and comparing them, we can identify the two swapped nodes. Once identified, we swap their values to correct the tree.
This method requires O(n) space to store the nodes' values where n is the number of nodes in the tree.
This Python solution performs an in-order traversal of the BST and stores the nodes in a list. It then iterates through this list to find the two nodes that are out of order, i.e., the swapped nodes, by checking where the current node value is less than the previous node value. Finally, it swaps the values of these nodes to correct the BST.
C++
Java
C
C#
JavaScript
Time Complexity: O(n) since we are conducting an in-order traversal of the tree.
Space Complexity: O(n) as we store nodes in a list for comparison.
This approach leverages Morris Traversal to achieve O(1) space complexity, without needing an auxiliary stack or recursion. Morris Traversal utilizes the tree structure itself to keep track of nodes and ensures the tree is reset to its original configuration after traversal. To correct the BST, we detect swapped nodes by identifying violation of BST properties during traversal, and then we swap these nodes to achieve a valid BST.
This Python solution uses Morris Inorder Traversal, which leverages the threads in the tree structure to avoid using additional space. While traversing, we establish temporary links (threads) to visiting nodes using their predecessor relations. We detect unordered node pairs and correct them by swapping their values.
C++
Java
C
C#
JavaScript
Time Complexity: O(n).
Space Complexity: O(1).
| Approach | Complexity |
|---|---|
| In-Order Traversal with Additional Space | Time Complexity: O(n) since we are conducting an in-order traversal of the tree. |
| Morris Traversal for Constant Space Complexity | Time Complexity: O(n). |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Inorder Traversal with Array | O(n) | O(n) | Good for understanding the BST property and debugging swapped nodes easily |
| Inorder Traversal with Tracking Pointers | O(n) | O(h) | Uses recursion/stack; cleaner than array approach and common in interviews |
| Morris Traversal (Threaded Tree) | O(n) | O(1) | Best when constant extra space is required or when optimizing traversal memory |
Validate Binary Search Tree - Depth First Search - Leetcode 98 • NeetCode • 257,702 views views
Watch 9 more video solutions →Practice Recover Binary Search Tree with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor