🧠
Brute Force (Rebuild Tree by Inorder Traversal)
💡 This approach exists to build intuition by explicitly collecting valid nodes and reconstructing the tree, showing the problem can be solved by filtering and rebuilding, but it is inefficient.
Intuition
Traverse the BST inorder to get a sorted list of node values, filter out values outside [low, high], then rebuild a balanced BST from the filtered list.
Algorithm
- Perform inorder traversal to collect all node values in sorted order.
- Filter the collected values to keep only those within [low, high].
- Rebuild a balanced BST from the filtered sorted list.
- Return the root of the rebuilt BST.
💡 The challenge is realizing that inorder traversal gives sorted nodes, and rebuilding a BST from sorted data is a classic problem, but this approach ignores BST pruning optimizations.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def inorder(root, arr):
if not root:
return
inorder(root.left, arr)
arr.append(root.val)
inorder(root.right, arr)
def build_bst(nums, start, end):
if start > end:
return None
mid = (start + end) // 2
root = TreeNode(nums[mid])
root.left = build_bst(nums, start, mid - 1)
root.right = build_bst(nums, mid + 1, end)
return root
def trimBST(root, low, high):
arr = []
inorder(root, arr)
filtered = [x for x in arr if low <= x <= high]
return build_bst(filtered, 0, len(filtered) - 1)
# Driver code to test
if __name__ == '__main__':
# Construct example tree
root = TreeNode(3)
root.left = TreeNode(0)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
root.left.right.left = TreeNode(1)
low, high = 1, 3
trimmed = trimBST(root, low, high)
# Simple print inorder to verify
def print_inorder(node):
if not node:
return
print_inorder(node.left)
print(node.val, end=' ')
print_inorder(node.right)
print_inorder(trimmed)
Line Notes
def inorder(root, arr):Defines helper to collect nodes inorder, exploiting BST sorted property
arr.append(root.val)Collects node values in sorted order due to inorder traversal
filtered = [x for x in arr if low <= x <= high]Filters out values outside the allowed range
def build_bst(nums, start, end):Builds balanced BST from sorted list by choosing mid as root
import java.util.*;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public class TrimBST {
public static void inorder(TreeNode root, List<Integer> arr) {
if (root == null) return;
inorder(root.left, arr);
arr.add(root.val);
inorder(root.right, arr);
}
public static TreeNode buildBST(List<Integer> nums, int start, int end) {
if (start > end) return null;
int mid = (start + end) / 2;
TreeNode root = new TreeNode(nums.get(mid));
root.left = buildBST(nums, start, mid - 1);
root.right = buildBST(nums, mid + 1, end);
return root;
}
public static TreeNode trimBST(TreeNode root, int low, int high) {
List<Integer> arr = new ArrayList<>();
inorder(root, arr);
List<Integer> filtered = new ArrayList<>();
for (int x : arr) {
if (x >= low && x <= high) filtered.add(x);
}
return buildBST(filtered, 0, filtered.size() - 1);
}
public static void printInorder(TreeNode root) {
if (root == null) return;
printInorder(root.left);
System.out.print(root.val + " ");
printInorder(root.right);
}
public static void main(String[] args) {
TreeNode root = new TreeNode(3);
root.left = new TreeNode(0);
root.right = new TreeNode(4);
root.left.right = new TreeNode(2);
root.left.right.left = new TreeNode(1);
int low = 1, high = 3;
TreeNode trimmed = trimBST(root, low, high);
printInorder(trimmed);
}
}
Line Notes
public static void inorder(TreeNode root, List<Integer> arr)Collects BST nodes in sorted order via inorder traversal
arr.add(root.val);Adds current node's value to list
List<Integer> filtered = new ArrayList<>();Creates list to hold values within range
return buildBST(filtered, 0, filtered.size() - 1);Rebuilds balanced BST from filtered sorted values
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
void inorder(TreeNode* root, vector<int>& arr) {
if (!root) return;
inorder(root->left, arr);
arr.push_back(root->val);
inorder(root->right, arr);
}
TreeNode* buildBST(const vector<int>& nums, int start, int end) {
if (start > end) return nullptr;
int mid = (start + end) / 2;
TreeNode* root = new TreeNode(nums[mid]);
root->left = buildBST(nums, start, mid - 1);
root->right = buildBST(nums, mid + 1, end);
return root;
}
TreeNode* trimBST(TreeNode* root, int low, int high) {
vector<int> arr;
inorder(root, arr);
vector<int> filtered;
for (int x : arr) {
if (x >= low && x <= high) filtered.push_back(x);
}
return buildBST(filtered, 0, (int)filtered.size() - 1);
}
void printInorder(TreeNode* root) {
if (!root) return;
printInorder(root->left);
cout << root->val << " ";
printInorder(root->right);
}
int main() {
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(0);
root->right = new TreeNode(4);
root->left->right = new TreeNode(2);
root->left->right->left = new TreeNode(1);
int low = 1, high = 3;
TreeNode* trimmed = trimBST(root, low, high);
printInorder(trimmed);
return 0;
}
Line Notes
void inorder(TreeNode* root, vector<int>& arr)Helper to collect BST nodes in sorted order
arr.push_back(root->val);Stores current node's value during inorder traversal
vector<int> filtered;Holds values within the specified range
return buildBST(filtered, 0, (int)filtered.size() - 1);Rebuilds BST from filtered sorted values
class TreeNode {
constructor(val=0, left=null, right=null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function inorder(root, arr) {
if (!root) return;
inorder(root.left, arr);
arr.push(root.val);
inorder(root.right, arr);
}
function buildBST(nums, start, end) {
if (start > end) return null;
let mid = Math.floor((start + end) / 2);
let root = new TreeNode(nums[mid]);
root.left = buildBST(nums, start, mid - 1);
root.right = buildBST(nums, mid + 1, end);
return root;
}
function trimBST(root, low, high) {
let arr = [];
inorder(root, arr);
let filtered = arr.filter(x => x >= low && x <= high);
return buildBST(filtered, 0, filtered.length - 1);
}
// Driver code
const root = new TreeNode(3);
root.left = new TreeNode(0);
root.right = new TreeNode(4);
root.left.right = new TreeNode(2);
root.left.right.left = new TreeNode(1);
const low = 1, high = 3;
const trimmed = trimBST(root, low, high);
function printInorder(node) {
if (!node) return;
printInorder(node.left);
console.log(node.val);
printInorder(node.right);
}
printInorder(trimmed);
Line Notes
function inorder(root, arr)Collects nodes in sorted order using inorder traversal
arr.push(root.val);Adds current node's value to array
let filtered = arr.filter(x => x >= low && x <= high);Filters out values outside the range
return buildBST(filtered, 0, filtered.length - 1);Rebuilds BST from filtered sorted values
Inorder traversal visits all nodes once (O(n)), filtering is O(n), and rebuilding BST from sorted array is O(n).
💡 For n=20 nodes, this means about 20 visits to collect, 20 checks to filter, and 20 steps to rebuild, totaling roughly 60 operations.
Interview Verdict: Accepted but inefficient for large trees due to extra space and rebuilding
This approach works but wastes time and memory rebuilding the tree instead of pruning in place, so it's good for understanding but not optimal.