Kth Smallest Element in BST in DSA Rust - Time & Space Complexity
We want to know how the time 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.
fn kth_smallest(root: &Option>, k: &mut i32) -> Option {
if let Some(node) = root {
if let Some(val) = kth_smallest(&node.left, k) {
return Some(val);
}
*k -= 1;
if *k == 0 {
return Some(node.val);
}
return kth_smallest(&node.right, k);
}
None
}
This code finds the kth smallest value by walking the tree in order (left, root, right).
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 the best case, or all n nodes in the worst case.
As the tree grows, the number of nodes visited depends on k and the tree shape.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 node visits |
| 100 | Up to 100 node visits |
| 1000 | Up to 1000 node visits |
Pattern observation: In the worst case, the steps grow linearly with the number of nodes.
Time Complexity: O(h + k)
This means the time depends on the tree height plus how far we go to find the kth smallest element.
[X] Wrong: "Finding the kth smallest always takes O(n) time because we must visit all nodes."
[OK] Correct: We stop once we find the kth smallest, so we often visit fewer than all nodes, especially if k is small or the tree is balanced.
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 vs completely skewed? How would the time complexity change?"
Practice
Kth Smallest Element in BST problem ask you to find?Solution
Step 1: Understand BST property
A Binary Search Tree (BST) stores elements so that left child nodes are smaller and right child nodes are larger.Step 2: Define Kth smallest element
The Kth smallest element is the element that appears in position K when all elements are sorted in ascending order.Final Answer:
The element that is the Kth smallest when the BST elements are sorted -> Option BQuick Check:
Kth smallest = Kth element in sorted order [OK]
- Confusing Kth smallest with largest element
- Thinking root is always Kth smallest
- Mixing up height with element value
Solution
Step 1: Understand Rust ownership for trees
Rust requires heap allocation for recursive types, so child nodes useBoxwrapped inOptionfor nullable children.Step 2: Check each struct definition
Option is correct; direct TreeNode fields cause infinite size; references need lifetimes and are not owned.Final Answer:
struct TreeNode { val: i32, left: Option, right: Option } -> Option AQuick Check:
Use Option for child nodes [OK]
- Using direct TreeNode fields causing infinite size error
- Using references without lifetimes
- Not wrapping children in Option for nullability
fn inorder(root: &Option, k: &mut i32, result: &mut Option<i32>) {
if let Some(node) = root {
inorder(&node.left, k, result);
*k -= 1;
if *k == 0 {
*result = Some(node.val);
return;
}
inorder(&node.right, k, result);
}
}
// BST: 3 <- 5 -> 7, k = 2
let root = Some(Box::new(TreeNode { val: 5, left: Some(Box::new(TreeNode { val: 3, left: None, right: None })), right: Some(Box::new(TreeNode { val: 7, left: None, right: None })) }));
let mut k = 2;
let mut result = None;
inorder(&root, &mut k, &mut result);
println!("{:?}", result);Solution
Step 1: Perform inorder traversal on BST
Inorder visits nodes in ascending order: 3, 5, 7.Step 2: Decrement k and check when k == 0
Visit 3: k=2->1; Visit 5: k=1->0, result=5, stop traversal.Final Answer:
Some(5) -> Option AQuick Check:
2nd smallest in [3,5,7] is 5 [OK]
- Confusing preorder or postorder with inorder
- Not decrementing k correctly
- Not stopping traversal after finding Kth element
fn kth_smallest(root: &Option, k: &mut i32) -> Option<i32> {
if let Some(node) = root {
let left = kth_smallest(&node.left, k);
*k -= 1;
if *k == 0 {
return Some(node.val);
}
let right = kth_smallest(&node.right, k);
return right;
}
None
}Solution
Step 1: Analyze traversal and return logic
The function returns Some(value) when Kth element found, but recursive calls continue after that.Step 2: Check if traversal stops after finding Kth element
Because recursive calls continue, traversal does not stop immediately, causing unnecessary work or wrong results.Final Answer:
The function does not stop traversal after finding the Kth element -> Option DQuick Check:
Traversal must stop once Kth element found [OK]
- Not returning early after finding Kth element
- Incorrect k decrement order
- Ignoring None base case
Solution
Step 1: List BST elements in sorted order
Inorder traversal of BST gives sorted nodes: 0, 2, 3, 4, 5, 6, 7, 8, 9.Step 2: Identify 4th smallest element
The 4th element in this sorted list is 4.Final Answer:
4 -> Option CQuick Check:
Sorted nodes: 0,2,3,4,... 4th is 4 [OK]
- Counting nodes incorrectly
- Confusing insertion order with sorted order
- Off-by-one errors in K counting
Ready to prove it?
Pass the test and this pattern moves unknown
