Bird
Raised Fist0
Interview Prepbinary-search-treesmediumAmazonGoogle

Trim a BST

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Steps
setup

Initialize root and parameters

The initial BST is constructed with root value 3, and the range [1,3] is set. No pruning has started yet.

💡 Setting up the tree and range is essential before pruning begins.
Line:root = TreeNode(3) root.left = TreeNode(0) root.right = TreeNode(4) low, high = 1, 3
💡 The tree structure and range are now ready for trimming.
📊
Trim a BST - Watch the Algorithm Execute, Step by Step
Watching each pointer move and subtree adjustment helps you understand how BST properties enable efficient pruning without recursion.
Step 1/11
·Active fillAnswer cell
Current node: 0
30421
Current node: 0
30421
Current node: 0
30421
DFS Stack
0 (entered)cur=0
Current node: 0
30421
DFS Stack
0 (left_done)cur=0
Current node: 3
30421
DFS Stack
0 (left_done)cur=3
Current node: 3
30421
DFS Stack
0 (left_done)cur=3
Current node: 4
30421
DFS Stack
0 (left_done)cur=4
Current node: 0
30421
DFS Stack
0 (right_entered)cur=0
Current node: 0
30421
DFS Stack
0 (right_done)cur=0
Current node: 4
30421
DFS Stack
0 (right_done)cur=4
Current node: 0
32104
Return: 0

Key Takeaways

The root is first moved to a valid node within the range before any pruning.

This step ensures the trimmed tree's root is always valid, which is not obvious from code alone.

Left subtree pruning removes nodes less than low by adjusting left pointers iteratively.

Seeing pointer updates visually clarifies how pruning avoids recursion and preserves BST structure.

Right subtree pruning removes nodes greater than high similarly by adjusting right pointers.

The symmetry of left and right pruning is easier to grasp when watching each pointer move.

Practice

(1/5)
1. You are given a binary tree where each node has a unique integer value. You need to find whether a given value exists in the tree efficiently by leveraging the tree's ordering properties. Which approach guarantees the fastest search in the worst case?
easy
A. Use the BST property to decide whether to search left or right subtree at each node, recursively or iteratively.
B. Perform a breadth-first search (BFS) to find the value level by level.
C. Traverse the entire tree recursively checking each node until the value is found.
D. Use dynamic programming to store previously searched subtrees to avoid repeated work.

Solution

  1. Step 1: Understand the problem constraints

    The tree is a BST, so left subtree nodes are less than the node, right subtree nodes are greater.
  2. Step 2: Identify the optimal search approach

    Using the BST property allows skipping half of the tree at each step, leading to O(h) time complexity.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    BST property guides search direction efficiently [OK]
Hint: BST property enables directed search, not full traversal [OK]
Common Mistakes:
  • Thinking BFS or full traversal is optimal for BST search
2. The following code attempts to implement a BST Iterator using the Morris traversal technique. Identify the bug that can cause the tree structure to remain corrupted after iteration.
class BSTIterator:
    def __init__(self, root):
        self.current = root
        self.next_val = None
        self._advance()

    def _advance(self):
        while self.current:
            if not self.current.left:
                self.next_val = self.current.val
                self.current = self.current.right
                return
            else:
                pre = self.current.left
                while pre.right and pre.right != self.current:
                    pre = pre.right
                if not pre.right:
                    pre.right = self.current
                    self.current = self.current.left
                else:
                    # BUG: Missing restoration of thread
                    self.next_val = self.current.val
                    self.current = self.current.right
medium
A. Line resetting pre.right to null is missing, so threads are not removed.
B. Line setting self.next_val = self.current.val is incorrect and should be removed.
C. Line moving self.current to self.current.left should be self.current.right instead.
D. Line initializing self.current = root in __init__ is incorrect and should be null.

Solution

  1. Step 1: Identify thread restoration step

    In Morris traversal, after visiting a node, the temporary thread (pre.right) must be reset to null to restore the tree.
  2. Step 2: Locate missing restoration

    The code omits resetting pre.right = None in the else block, causing the tree to remain modified after iteration.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Missing thread removal corrupts tree structure [OK]
Hint: Always restore threads to avoid tree corruption [OK]
Common Mistakes:
  • Forgetting to remove threads
  • Misplacing next_val assignment
  • Incorrect current pointer updates
3. What is the time complexity of the optimal iterative approach that converts a BST to a Greater Tree using reverse inorder traversal with an explicit stack?
medium
A. O(n) where n is the number of nodes in the BST
B. O(n · h) where n is number of nodes and h is tree height
C. O(n · log n) due to stack operations on balanced BST
D. O(h) where h is the height of the BST because each node is visited once

Solution

  1. Step 1: Identify number of nodes visited

    Each node is visited exactly once during traversal.
  2. Step 2: Analyze stack operations and overall traversal

    While each node is visited once, the explicit stack can hold up to h nodes, and each push/pop operation can be considered O(1). However, in the worst case (unbalanced tree), the height h can be up to n, making the complexity O(n * h).
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Worst-case complexity depends on tree height [OK]
Hint: Worst-case complexity depends on tree height [OK]
Common Mistakes:
  • Assuming stack operations multiply complexity by height unnecessarily
  • Confusing recursion stack space with time complexity
  • Thinking balanced BST implies O(n log n) time
4. Suppose the problem is extended so that multiple pairs of nodes (more than two nodes) are swapped in the BST, possibly non-adjacent. Which of the following modifications to the recovery algorithm is correct and efficient?
hard
A. Use the Morris inorder traversal to detect all violations and store all nodes involved, then sort their values and reassign in inorder traversal.
B. Run the Morris traversal multiple times, each time swapping the first detected violation nodes until no violations remain.
C. Use the brute force approach: inorder traversal to collect all values, sort them, then overwrite the tree nodes in inorder traversal.
D. Modify the Morris traversal to swap nodes immediately upon detecting each violation without storing nodes, fixing all swaps in one pass.

Solution

  1. Step 1: Understand the problem extension

    Multiple pairs of nodes swapped means multiple violations, possibly complex to detect and fix in one pass.
  2. Step 2: Evaluate approaches

    Morris traversal detects only two nodes swapped optimally; multiple swaps require collecting all values, sorting, and rewriting nodes, which brute force does efficiently.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Brute force approach handles multiple swaps correctly by sorting all values [OK]
Hint: Multiple swaps require full value sorting and rewriting [OK]
Common Mistakes:
  • Assuming Morris traversal can fix multiple swaps in one pass
  • Trying to swap nodes immediately without full detection
  • Running multiple passes of Morris traversal inefficiently
5. Suppose the BST validation problem is modified so that duplicate values are allowed only on the right subtree (i.e., node values in the right subtree can be equal to the current node). Which modification to the inorder traversal check correctly validates this variant?
hard
A. Change the comparison to node.val < prev[0] to allow duplicates on the right subtree.
B. Change the comparison to node.val < prev[0] for all nodes except when node is right child, then allow node.val == prev[0].
C. Change the comparison to node.val <= prev[0] to allow duplicates anywhere.
D. Change the comparison to node.val < prev[0] only when traversing left subtree, and node.val <= prev[0] when traversing right subtree.

Solution

  1. Step 1: Understand variant allowing duplicates only on right subtree

    Duplicates allowed only if they appear in right subtree, so inorder sequence can have equal values only when moving right.
  2. Step 2: Modify comparison accordingly

    During inorder traversal, allow node.val == prev[0] only if current node is right child of previous node; otherwise, enforce strict inequality.
  3. Step 3: Reason why other options fail

    Change the comparison to node.val < prev[0] to allow duplicates on the right subtree. allows duplicates anywhere; Change the comparison to node.val <= prev[0] to allow duplicates anywhere. allows duplicates anywhere; Change the comparison to node.val < prev[0] only when traversing left subtree, and node.val <= prev[0] when traversing right subtree. is ambiguous and not implementable in simple inorder traversal without parent info.
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Allow duplicates only on right subtree requires conditional equality check [OK]
Hint: Duplicates allowed only on right subtree require conditional comparison [OK]
Common Mistakes:
  • Allowing duplicates anywhere
  • Ignoring subtree direction in comparison
  • Using simple <= everywhere