Kth Smallest Element in BST in DSA C# - Time & Space Complexity
We want to understand how long it takes to find the kth smallest value in a Binary Search Tree (BST).
How does the time needed grow as the tree or k gets bigger?
Analyze the time complexity of the following code snippet.
public int KthSmallest(TreeNode root, int k) {
int count = 0;
int result = 0;
bool InOrder(TreeNode node) {
if (node == null) return false;
if (InOrder(node.left)) return true;
count++;
if (count == k) {
result = node.val;
return true;
}
return InOrder(node.right);
}
InOrder(root);
return result;
}
This code finds the kth smallest element by visiting nodes in order from smallest to largest.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive in-order traversal of the BST nodes.
- How many times: Visits nodes until the kth smallest is found, up to k times in best case, up to n times in worst case (n = total nodes).
As the tree size grows, the number of nodes visited depends on k and tree shape.
| Input Size (n) | Approx. Operations (nodes visited) |
|---|---|
| 10 | Up to 10 (if k=10) |
| 100 | Up to 100 (if k=100) |
| 1000 | Up to 1000 (if k=1000) |
Pattern observation: The work grows roughly with k, but in worst case can be as large as n if k is near n.
Time Complexity: O(h + k)
This means the time grows with the height of the tree plus the kth position we want to find.
[X] Wrong: "The time is always O(n) because we might visit all nodes."
[OK] Correct: If the tree is balanced and k is small, we only visit a small part of the tree, so time depends on k and tree height, not always all nodes.
Understanding this time complexity helps you explain how tree shape and k affect performance, a key skill for working with search trees in real projects.
"What if the BST is replaced by a balanced tree with stored subtree sizes? 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 Kth smallest element, meaning the element that would appear in position K if the BST elements were sorted.Step 2: Recognize BST property
In a BST, an inorder traversal visits nodes in ascending order, so the Kth visited node is the Kth smallest.Final Answer:
The element that is the Kth smallest value in the Binary Search Tree -> Option CQuick Check:
Kth smallest = Kth visited in inorder traversal [OK]
- Confusing Kth smallest with Kth largest
- Ignoring BST property and sorting separately
- Using preorder or postorder traversal instead of inorder
TreeNode?Solution
Step 1: Identify correct parameter types
The method needs the root node of type TreeNode and an integer k to find the Kth smallest element.Step 2: Check return type and parameters
The method returns an int (the value of the Kth smallest node) and takes TreeNode root and int k as parameters.Final Answer:
public int KthSmallest(TreeNode root, int k) -> Option AQuick Check:
Correct signature includes root node and k as parameters [OK]
- Using void return type instead of int
- Missing root node parameter
- Using wrong parameter types
k = 3, what will the following C# code print?class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int v) { val = v; }
}
// BST structure:
// 5
// / \
// 3 7
// / \ \
// 2 4 8
int KthSmallest(TreeNode root, int k) {
List<int> vals = new List<int>();
void Inorder(TreeNode node) {
if (node == null) return;
Inorder(node.left);
vals.Add(node.val);
Inorder(node.right);
}
Inorder(root);
return vals[k - 1];
}
TreeNode root = new TreeNode(5);
root.left = new TreeNode(3);
root.right = new TreeNode(7);
root.left.left = new TreeNode(2);
root.left.right = new TreeNode(4);
root.right.right = new TreeNode(8);
Console.WriteLine(KthSmallest(root, 3));Solution
Step 1: Perform inorder traversal of BST
Inorder traversal visits nodes in ascending order: 2, 3, 4, 5, 7, 8.Step 2: Find the 3rd element in the sorted list
The 3rd element (index 2) is 4.Final Answer:
4 -> Option AQuick Check:
Inorder sorted list = [2,3,4,5,7,8], 3rd element = 4 [OK]
- Using preorder or postorder traversal order
- Off-by-one error in indexing k-1
- Confusing left and right subtree values
int KthSmallest(TreeNode root, int k) {
int count = 0;
int result = -1;
void Inorder(TreeNode node) {
if (node == null) return;
Inorder(node.left);
count++;
if (count == k) {
result = node.val;
return;
}
Inorder(node.right);
}
Inorder(root);
return result;
}Solution
Step 1: Analyze the recursive Inorder function
The return statement inside Inorder only exits the current call, not the entire traversal, so traversal continues after finding the Kth element.Step 2: Understand why this is problematic
Continuing traversal after setting result wastes time and space; no mechanism to stop recursion early.Final Answer:
The return inside Inorder does not stop the entire traversal -> Option DQuick Check:
Return in recursion stops only current call, not whole traversal [OK]
- Assuming return stops all recursion
- Not using a flag to stop traversal after finding element
- Ignoring null root case
Options:
A) Use an iterative inorder traversal with a stack and stop when the Kth element is found.
B) Perform a full inorder traversal and store all elements in a list, then return the Kth element.
C) Convert the BST to a sorted array by any method, then binary search for the Kth element.
D) Use preorder traversal and count nodes until K is reached.
Solution
Step 1: Evaluate full inorder traversal approach
Storing all elements uses extra space and time, not efficient for large trees.Step 2: Consider iterative inorder traversal with early stop
This approach uses a stack to traverse nodes in order and stops immediately after finding the Kth smallest, saving time and space.Step 3: Analyze other options
Binary search requires sorted array, which needs full traversal first; preorder traversal does not guarantee sorted order.Final Answer:
Use iterative inorder traversal with stack, stop at Kth element -> Option BQuick Check:
Iterative inorder + early stop = efficient Kth smallest search [OK]
- Using full traversal wasting memory
- Using preorder which is unsorted
- Trying binary search without sorted array
Ready to prove it?
Pass the test and this pattern moves unknown
