Imagine you have a Binary Search Tree (BST) and need to split it into two separate trees based on a target value. This is like organizing a library where you want to separate books into two sections: one for books with ID numbers ≤ target, and another for books with ID numbers > target.
Given the root of a BST and an integer target, you need to split the tree into two subtrees:
Left subtree: Contains all nodes with values ≤ target
Right subtree: Contains all nodes with values > target
The challenge is to preserve the original tree structure as much as possible. If a parent-child relationship existed in the original tree and both nodes end up in the same subtree, that relationship should be maintained.
Important: The target value might not exist in the tree, but you still need to perform the split based on that value.
Return an array [leftRoot, rightRoot] where leftRoot is the root of the subtree with values ≤ target, and rightRoot is the root of the subtree with values > target.
The optimal recursive approach leverages BST properties to split the tree in O(n) time while preserving the original structure. At each node, we decide which result tree it belongs to based on the target comparison, then recursively split the appropriate subtree and connect the results properly.
Common Approaches
✓
Brute Force (Inorder + Rebuild)
⏱️ Time: O(n²)
Space: O(n)
First perform an inorder traversal to collect all values, separate them based on the target, then construct two new BSTs from the separated values. This approach completely rebuilds the trees.
Optimal Recursive Split
⏱️ Time: O(n)
Space: O(h)
Use the BST property to recursively determine where to split the tree. At each node, decide whether it belongs in the left or right result tree, and recursively split its subtrees accordingly. This preserves the original structure.
Brute Force (Inorder + Rebuild) — Algorithm Steps
Perform inorder traversal to collect all node values
Separate values into two arrays based on target
Build new BST from values ≤ target
Build new BST from values > target
Return roots of both new trees
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Traverse Original
Perform inorder traversal to collect all values
2
Separate Values
Split values based on target into two arrays
3
Rebuild Trees
Construct two new BSTs from the separated values
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
struct TreeNode* createNode(int val) {
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
node->val = val;
node->left = node->right = NULL;
return node;
}
struct TreeNode** splitBST(struct TreeNode* root, int target, int* returnSize) {
*returnSize = 2;
struct TreeNode** result = (struct TreeNode**)malloc(2 * sizeof(struct TreeNode*));
if (!root) {
result[0] = result[1] = NULL;
return result;
}
if (root->val <= target) {
// Current node goes to left tree
struct TreeNode* leftRoot = root;
// Recursively split right subtree
int subSize;
struct TreeNode** subResult = splitBST(root->right, target, &subSize);
// Attach left part of right subtree to current node
leftRoot->right = subResult[0];
result[0] = leftRoot;
result[1] = subResult[1];
free(subResult);
return result;
} else {
// Current node goes to right tree
struct TreeNode* rightRoot = root;
// Recursively split left subtree
int subSize;
struct TreeNode** subResult = splitBST(root->left, target, &subSize);
// Attach right part of left subtree to current node
rightRoot->left = subResult[1];
result[0] = subResult[0];
result[1] = rightRoot;
free(subResult);
return result;
}
}
struct TreeNode* buildTree(char arr[][20], int size) {
if (size == 0 || strcmp(arr[0], "null") == 0) {
return NULL;
}
struct TreeNode** nodes = (struct TreeNode**)malloc(size * sizeof(struct TreeNode*));
for (int i = 0; i < size; i++) {
if (strcmp(arr[i], "null") == 0) {
nodes[i] = NULL;
} else {
nodes[i] = createNode(atoi(arr[i]));
}
}
for (int i = 0; i < size; i++) {
if (nodes[i] != NULL) {
int leftIdx = 2 * i + 1;
int rightIdx = 2 * i + 2;
if (leftIdx < size) {
nodes[i]->left = nodes[leftIdx];
}
if (rightIdx < size) {
nodes[i]->right = nodes[rightIdx];
}
}
}
struct TreeNode* root = nodes[0];
free(nodes);
return root;
}
void treeToArray(struct TreeNode* root, char result[][20], int* size) {
if (!root) {
*size = 0;
return;
}
struct TreeNode* queue[1000];
int front = 0, rear = 0;
queue[rear++] = root;
*size = 0;
while (front < rear) {
struct TreeNode* node = queue[front++];
if (node) {
sprintf(result[(*size)++], "%d", node->val);
queue[rear++] = node->left;
queue[rear++] = node->right;
} else {
strcpy(result[(*size)++], "null");
}
}
// Remove trailing nulls
while (*size > 0 && strcmp(result[*size - 1], "null") == 0) {
(*size)--;
}
}
void formatArray(char arr[][20], int size, char* output) {
if (size == 0) {
strcpy(output, "[]");
return;
}
strcpy(output, "[");
for (int i = 0; i < size; i++) {
if (i > 0) strcat(output, ",");
strcat(output, arr[i]);
}
strcat(output, "]");
}
void parseArray(const char* str, int* arr, int* size) {
*size = 0;
const char* p = str;
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0') break;
arr[(*size)++] = (int)strtol(p, (char**)&p, 10);
}
}
int main() {
char treeInput[1000];
int target;
fgets(treeInput, sizeof(treeInput), stdin);
scanf("%d", &target);
// Remove newline
treeInput[strcspn(treeInput, "\n")] = 0;
char arr[100][20];
int arrSize = 0;
if (strlen(treeInput) > 0) {
char* token = strtok(treeInput, ",");
while (token != NULL) {
strcpy(arr[arrSize++], token);
token = strtok(NULL, ",");
}
}
struct TreeNode* root = buildTree(arr, arrSize);
int returnSize;
struct TreeNode** result = splitBST(root, target, &returnSize);
char leftArr[100][20], rightArr[100][20];
int leftSize, rightSize;
treeToArray(result[0], leftArr, &leftSize);
treeToArray(result[1], rightArr, &rightSize);
char leftFormatted[1000], rightFormatted[1000];
formatArray(leftArr, leftSize, leftFormatted);
formatArray(rightArr, rightSize, rightFormatted);
printf("[%s,%s]\n", leftFormatted, rightFormatted);
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n²)
O(n) for traversal + O(n²) worst case for rebuilding unbalanced trees
n
2n
⚠ Quadratic Growth
Space Complexity
O(n)
O(n) for storing values + O(n) for recursion stack
n
2n
⚡ Linearithmic Space
23.5K Views
MediumFrequency
~15 minAvg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.