Difficulty | Source | Tags | ||
---|---|---|---|---|
Hard |
160 Days of Problem Solving |
|
The problem can be found at the following link: Question Link
Given the root of a Binary Search Tree (BST), where exactly two nodes were swapped by mistake, your task is to fix (or correct) the BST by swapping them back. The structure of the tree should not change.
10
/ \
5 8
/ \
2 20

1

The nodes 20 and 8 were swapped by mistake. After swapping them back, the BST is restored correctly.
5
/ \
10 20
/ \
2 8

1

The nodes 10 and 5 were swapped by mistake. After swapping them back, the BST is restored correctly.
$(1 \leq \text{Number of Nodes} \leq 10^3)$
- Use an inorder traversal to detect swapped nodes in the BST.
- Identify the two misplaced nodes:
- If a node appears larger than the next node, it's incorrectly placed.
- Track the first misplaced node and the second misplaced node.
- Swap the values of the two misplaced nodes to restore the BST.
- Perform an inorder traversal to find the two misplaced nodes.
- If the first misplaced node is found, store it in
first
. - If a second misplaced node is found later, store it in
last
. - If there's no second misplaced node, use the
middle
node instead. - Swap the values of the two misplaced nodes.
- Expected Time Complexity:
O(N)
, since we traverse each node once. - Expected Auxiliary Space Complexity:
O(H)
, due to the recursion stack in the inorder traversal.
class Solution {
public:
void correctBST(Node* root) {
Node *first = nullptr, *middle = nullptr, *last = nullptr, *prev = nullptr;
function<void(Node*)> inorder = [&](Node* node) {
if (!node) return;
inorder(node->left);
if (prev && node->data < prev->data) {
if (!first) first = prev, middle = node;
else last = node;
}
prev = node;
inorder(node->right);
};
inorder(root);
swap(first->data, last ? last->data : middle->data);
}
};
- Use a stack for inorder traversal (instead of recursion).
- Detect swapped nodes by checking the inorder order.
- Swap the incorrect nodes back to restore the BST.
class Solution {
public:
void correctBST(Node* root) {
stack<Node*> st;
Node *first = nullptr, *middle = nullptr, *last = nullptr, *prev = nullptr;
while (!st.empty() || root) {
while (root) {
st.push(root);
root = root->left;
}
root = st.top(); st.pop();
if (prev && root->data < prev->data) {
if (!first) first = prev, middle = root;
else last = root;
}
prev = root;
root = root->right;
}
swap(first->data, last ? last->data : middle->data);
}
};
πΉ Avoids recursion stack overflow issues using an explicit stack.
- Use Morris Traversal to perform an inorder traversal without extra space.
- Identify misplaced nodes while modifying the BST structure temporarily.
- Restore the BST by swapping the misplaced nodes.
class Solution {
public:
void correctBST(Node* root) {
Node *first = nullptr, *middle = nullptr, *last = nullptr, *prev = nullptr;
while (root) {
if (!root->left) {
if (prev && root->data < prev->data) {
if (!first) first = prev, middle = root;
else last = root;
}
prev = root;
root = root->right;
} else {
Node* pre = root->left;
while (pre->right && pre->right != root) pre = pre->right;
if (!pre->right) {
pre->right = root;
root = root->left;
} else {
pre->right = nullptr;
if (prev && root->data < prev->data) {
if (!first) first = prev, middle = root;
else last = root;
}
prev = root;
root = root->right;
}
}
}
swap(first->data, last ? last->data : middle->data);
}
};
πΉ Uses O(1)
space without recursion or extra stack.
Approach | β±οΈ Time Complexity | ποΈ Space Complexity | β‘ Method | β Pros | |
---|---|---|---|---|---|
Recursive Inorder | π’ O(N) |
π‘ O(H) |
Recursion | Simple and easy to implement | Uses recursion stack space |
Iterative Inorder | π’ O(N) |
π‘ O(H) |
Stack-based | Avoids recursion depth issues | Uses extra memory for stack |
Morris Traversal | π’ O(N) |
π’ O(1) |
No extra space | No additional memory needed | Modifies tree temporarily |
- β
For space efficiency: Morris Traversal (
O(1)
space). - β For simplicity: Recursive Inorder Traversal.
- β For large trees: Iterative Inorder Traversal avoids recursion depth issues.
class Solution {
Node first, middle, last, prev;
void inorder(Node root) {
if (root == null) return;
inorder(root.left);
if (prev != null && root.data < prev.data) {
if (first == null) {
first = prev;
middle = root;
} else {
last = root;
}
}
prev = root;
inorder(root.right);
}
void correctBST(Node root) {
first = middle = last = prev = null;
inorder(root);
int temp = first.data;
first.data = (last != null) ? last.data : middle.data;
if (last != null) last.data = temp;
else middle.data = temp;
}
}
class Solution:
def correctBST(self, root):
self.first = self.middle = self.last = self.prev = None
def inorder(node):
if not node:
return
inorder(node.left)
if self.prev and node.data < self.prev.data:
if not self.first:
self.first, self.middle = self.prev, node
else:
self.last = node
self.prev = node
inorder(node.right)
inorder(root)
self.first.data, (self.last or self.middle).data = (self.last or self.middle).data, self.first.data
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: Any Questions. Letβs make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β