Bird
Raised Fist0
Interview Prepbinary-search-treeshardAmazonGoogleMicrosoft

Recover Binary Search Tree (Two Nodes Swapped)

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize pointers and start at root

Initialize first, second, and prev pointers to None. Set current pointer to root node (value 1).

💡 Setting up pointers is essential to track nodes during traversal and detect violations.
Line:first = second = prev = None current = root
💡 We start traversal at the root with no nodes visited yet.
📊
Recover Binary Search Tree (Two Nodes Swapped) - Watch the Algorithm Execute, Step by Step
Watching the algorithm step-by-step reveals how the Morris traversal avoids extra space and how the swapped nodes are identified by violations in inorder sequence.
Step 1/10
·Active fill★Answer cell
Current node: 1
132
132
Current node: 2
132
Current node: 2
132
Current node: 3
132
Current node: 3
132
132
312
312
312
Return: "[3,1,null,null,2]"

Key Takeaways

✓ Morris inorder traversal allows O(1) space traversal by temporarily modifying tree links.

This is hard to see from code alone because the threaded links are subtle and invisible without visualization.

✓ Violations in inorder sequence (prev.val > current.val) identify the two swapped nodes.

Visualizing the comparisons clarifies how the algorithm detects exactly which nodes to swap.

✓ Swapping values of the two identified nodes restores the BST without changing tree structure.

Seeing the final swap in the tree confirms the correctness of the approach beyond just code logic.

Practice

(1/5)
1. Consider the following Python code implementing BST validation using inorder traversal. What is the output of the program when run with the given test cases?
easy
A. true followed by false
B. true followed by true
C. false followed by true
D. false followed by false

Solution

  1. Step 1: Trace first tree (2,1,3)

    Inorder traversal yields [1,2,3], strictly increasing, so returns true.
  2. Step 2: Trace second tree (5,1,4 with children 3 and 6)

    Inorder traversal yields [1,5,3,4,6], 3 < 5 violates BST property, so returns false.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    First tree valid BST, second invalid due to subtree violation [OK]
Hint: Inorder traversal must be strictly increasing [OK]
Common Mistakes:
  • Assuming subtree root comparison is enough
  • Confusing output order
  • Missing strict inequality check
2. What is the time complexity of balancing a BST using the optimal approach of inorder traversal followed by iterative balanced BST construction from the collected nodes?
medium
A. O(n log n) due to sorting nodes during traversal
B. O(n) because inorder traversal and balanced rebuild each take linear time
C. O(n^2) because rebuilding the tree involves repeated subtree constructions
D. O(n) for traversal but O(n log n) for balanced tree construction

Solution

  1. Step 1: Analyze inorder traversal time

    Inorder traversal visits each node once -> O(n).
  2. Step 2: Analyze balanced BST construction time

    Rebuilding uses indices to pick middle nodes without extra sorting -> O(n).
  3. Step 3: Consider sorting complexity

    Although inorder traversal produces sorted nodes, if sorting is mistakenly applied, complexity becomes O(n log n).
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Sorting nodes during traversal leads to O(n log n) [Trap]
Hint: Beware of sorting overhead; if sorting is done, complexity is O(n log n)
Common Mistakes:
  • Assuming sorting is not needed, leading to O(n)
  • Thinking recursive rebuild is O(n^2) due to repeated subtree calls
  • Confusing traversal and construction complexities
3. What is the average time complexity per call of next() in the Morris traversal based BST Iterator, assuming the BST has n nodes?
medium
A. O(1) amortized per next() call because each edge is visited at most twice.
B. O(n) per next() call because each call may traverse the entire tree.
C. O(h) per next() call where h is the tree height due to traversing left children.
D. O(log n) per next() call assuming a balanced BST and stack usage.

Solution

  1. Step 1: Understand Morris traversal edge visits

    Each edge in the BST is visited at most twice: once to create a thread and once to remove it.
  2. Step 2: Calculate amortized cost per next()

    Since total work is O(n) for n nodes, and there are n calls to next(), average cost per call is O(1) amortized.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Amortized O(1) per next() matches Morris traversal properties [OK]
Hint: Morris traversal visits edges twice total [OK]
Common Mistakes:
  • Assuming worst-case O(n) per call
  • Confusing with stack-based O(h)
  • Ignoring amortized analysis
4. The following code attempts to convert a BST to a Greater Tree using reverse inorder traversal. Identify the line that contains a subtle bug causing incorrect node values.
medium
A. Line 8: node = node.left instead of node = node.right
B. Line 6: while node: loop condition
C. Line 10: acc_sum += node.val accumulation
D. Line 12: node = node.right traversal after updating node

Solution

  1. Step 1: Understand traversal order needed

    Reverse inorder traversal requires visiting right subtree first to accumulate greater values.
  2. Step 2: Identify incorrect subtree traversal

    Line 8 incorrectly moves to left child first, reversing traversal order and causing wrong sums.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Changing node = node.left to node = node.right fixes traversal order [OK]
Hint: Reverse inorder must traverse right subtree first [OK]
Common Mistakes:
  • Swapping left and right subtree traversal order
  • Resetting acc_sum inside loops
  • Updating node values before traversing right subtree
5. Suppose the BST can contain duplicate values and you want to find if there exist two nodes (not necessarily distinct) whose values sum to k. Which modification to the optimal inorder + two-pointer approach correctly handles this scenario?
hard
A. Perform inorder traversal and remove duplicates before applying two-pointer technique.
B. Use the same two-pointer approach but allow left and right pointers to point to the same index.
C. Use a hash set to store values and check complements, ignoring duplicates.
D. During two-pointer traversal, if left == right, check if the value at that index appears at least twice in the BST.

Solution

  1. Step 1: Understand duplicates and two-pointer constraints

    Two-pointer approach requires two distinct indices; if pointers meet, need to verify if duplicate values exist.
  2. Step 2: Modify check when left == right

    Check if the value at that index occurs at least twice in the BST to allow sum with itself.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Only During two-pointer traversal, if left == right, check if the value at that index appears at least twice in the BST. correctly handles duplicates without breaking two-pointer logic [OK]
Hint: Check duplicates count when pointers meet [OK]
Common Mistakes:
  • Allowing pointers to be equal without duplicate check
  • Removing duplicates loses valid pairs
  • Ignoring duplicates in hash set approach
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard