Kth Smallest Element in BST in DSA C++ - Time & Space Complexity
We want to understand how the time needed to find the kth smallest element in a Binary Search Tree changes as the tree grows.
How does the number of steps grow when the tree has more nodes?
Analyze the time complexity of the following code snippet.
int count = 0;
int result = -1;
bool found = false;
void inorder(TreeNode* root, int k) {
if (!root || found) return;
inorder(root->left, k);
if (found) return;
count++;
if (count == k) {
result = root->val;
found = true;
return;
}
inorder(root->right, k);
}
int kthSmallest(TreeNode* root, int k) {
count = 0;
result = -1;
found = false;
inorder(root, k);
return result;
}
This code does an in-order traversal of the BST to find the kth smallest element by counting nodes visited.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive in-order traversal visiting nodes.
- How many times: Visits nodes until the kth smallest is found, up to k nodes.
As the tree grows, the traversal visits nodes in order until it reaches the kth smallest.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to k nodes visited (k ≤ 10) |
| 100 | Up to k nodes visited (k ≤ 100) |
| 1000 | Up to k nodes visited (k ≤ 1000) |
Pattern observation: The number of steps grows roughly with k, not necessarily with total nodes n.
Time Complexity: O(h + k)
This means the time depends on the tree height h plus the number of nodes k we visit to find the kth smallest.
[X] Wrong: "The time is always O(n) because we might visit all nodes."
[OK] Correct: We stop as soon as we find the kth smallest, so we usually visit fewer than all nodes, especially if k is small.
Understanding this time complexity helps you explain how tree shape and k affect performance, a key skill in coding interviews.
"What if the BST is balanced versus completely skewed? How would the time complexity change?"
Practice
Kth Smallest Element in BST problem ask you to find?Solution
Step 1: Understand the problem statement
The problem asks to find the element that is the Kth smallest in the BST, meaning the element that would appear in position K if the BST elements were sorted.Step 2: Clarify what Kth smallest means in BST context
Since BST stores elements in sorted order when traversed in-order, the Kth smallest element is the Kth element visited in an in-order traversal.Final Answer:
The element that is the Kth smallest value in the Binary Search Tree -> Option BQuick Check:
Kth smallest element = Kth element in in-order traversal [OK]
- Confusing Kth smallest with Kth largest
- Thinking it's about tree height
- Summing elements instead of finding one
struct TreeNode { int val; TreeNode* left; TreeNode* right; };?Solution
Step 1: Check parameter types for BST traversal
The function should receive a pointer to the root node to traverse the BST properly, soTreeNode* rootis correct.Step 2: Check parameters for K value
K is an integer input, so passing it asint kis correct. The function returns the Kth smallest value as an integer.Final Answer:
int kthSmallest(TreeNode* root, int k); -> Option AQuick Check:
Pointer to root + int k parameter = correct signature [OK]
- Passing root by value instead of pointer
- Missing K parameter
- Wrong return type or missing return
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
int count = 0;
int result = -1;
void inorder(TreeNode* root, int k) {
if (!root) return;
inorder(root->left, k);
count++;
if (count == k) {
result = root->val;
return;
}
inorder(root->right, k);
}
int main() {
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(1);
root->right = new TreeNode(4);
root->left->right = new TreeNode(2);
inorder(root, 2);
std::cout << result << std::endl;
return 0;
}Solution
Step 1: Perform in-order traversal on the BST
The BST elements in in-order are visited as: 1, 2, 3, 4.Step 2: Identify the 2nd element visited
The 1st element visited is 1, the 2nd is 2, so result will be set to 2.Final Answer:
2 -> Option AQuick Check:
In-order 2nd element = 2 [OK]
- Confusing pre-order or post-order traversal
- Off-by-one error in counting
- Not stopping traversal after finding Kth element
int count = 0;
int result = -1;
void inorder(TreeNode* root, int k) {
if (!root) return;
inorder(root->left, k);
if (count == k) {
result = root->val;
return;
}
count++;
inorder(root->right, k);
}Solution
Step 1: Analyze the order of count checks and increments
The code checks if count == k before incrementing count, so it skips setting result when count reaches k.Step 2: Understand impact on finding Kth element
Because count is checked before increment, the Kth element is never assigned to result, causing incorrect behavior.Final Answer:
The check for count == k is before incrementing count, so it misses the Kth element -> Option DQuick Check:
Check count after increment, not before [OK]
- Checking count before incrementing
- Ignoring early return after finding Kth element
- Assuming global variables cause error
Solution
Step 1: Evaluate space and time efficiency of each approach
Store all elements then pick Kth; uses extra space to store all elements, which is not efficient. Convert to array then binary search; unnecessary overhead also uses extra space and unnecessary binary search. Breadth-first traversal; does not guarantee sorted order, so it won't find the Kth smallest correctly.Step 2: Identify the best approach
Recursive in-order traversal with counter; stops early uses recursive in-order traversal which visits nodes in sorted order and stops once the Kth element is found, saving time and space.Final Answer:
Recursive in-order traversal with counter; stops early -> Option CQuick Check:
In-order traversal + early stop = efficient Kth smallest [OK]
- Using extra space unnecessarily
- Using traversal that doesn't preserve order
- Not stopping traversal after finding Kth element
Ready to prove it?
Pass the test and this pattern moves unknown
