🧠
Brute Force (Inorder Traversal with Full List)
💡 This approach exists to build intuition by fully traversing the BST and collecting all elements in sorted order, which is straightforward but not optimal for large trees.
Intuition
Perform an inorder traversal to get all node values in sorted order, then return the kth element from the list.
Algorithm
- Traverse the BST inorder and store all node values in a list.
- After traversal, the list is sorted because of BST properties.
- Return the element at index k-1 from the list.
💡 The main challenge is understanding that inorder traversal of BST yields sorted order, making it easy to pick kth smallest after traversal.
from typing import Optional, List
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def kthSmallest(root: Optional[TreeNode], k: int) -> int:
def inorder(node: Optional[TreeNode], acc: List[int]):
if not node:
return
inorder(node.left, acc)
acc.append(node.val)
inorder(node.right, acc)
elements = []
inorder(root, elements)
return elements[k-1]
# Driver code to test
if __name__ == '__main__':
# Construct BST: [3,1,4,null,2]
root = TreeNode(3)
root.left = TreeNode(1)
root.right = TreeNode(4)
root.left.right = TreeNode(2)
print(kthSmallest(root, 1)) # Output: 1
Line Notes
def inorder(node: Optional[TreeNode], acc: List[int]):Defines helper function to collect nodes inorder
if not node:Base case to stop recursion at leaf's child
inorder(node.left, acc)Traverse left subtree first to get smaller elements
acc.append(node.val)Add current node's value after left subtree to maintain sorted order
inorder(node.right, acc)Traverse right subtree for larger elements
elements = []Initialize list to store inorder traversal results
inorder(root, elements)Start traversal from root
return elements[k-1]Return kth smallest element from sorted list
import java.util.*;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int val) { this.val = val; }
}
public class Solution {
public int kthSmallest(TreeNode root, int k) {
List<Integer> elements = new ArrayList<>();
inorder(root, elements);
return elements.get(k - 1);
}
private void inorder(TreeNode node, List<Integer> acc) {
if (node == null) return;
inorder(node.left, acc);
acc.add(node.val);
inorder(node.right, acc);
}
// Driver code
public static void main(String[] args) {
TreeNode root = new TreeNode(3);
root.left = new TreeNode(1);
root.right = new TreeNode(4);
root.left.right = new TreeNode(2);
Solution sol = new Solution();
System.out.println(sol.kthSmallest(root, 1)); // Output: 1
}
}
Line Notes
List<Integer> elements = new ArrayList<>();Create list to hold inorder traversal
inorder(root, elements);Start inorder traversal from root
if (node == null) return;Base case to stop recursion
acc.add(node.val);Add current node value after left subtree traversal
return elements.get(k - 1);Return kth smallest element from sorted list
public static void main(String[] args)Driver code to test the solution
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
void inorder(TreeNode* node, vector<int>& acc) {
if (!node) return;
inorder(node->left, acc);
acc.push_back(node->val);
inorder(node->right, acc);
}
int kthSmallest(TreeNode* root, int k) {
vector<int> elements;
inorder(root, elements);
return elements[k - 1];
}
};
int main() {
TreeNode* root = new TreeNode(3);
root->left = new TreeNode(1);
root->right = new TreeNode(4);
root->left->right = new TreeNode(2);
Solution sol;
cout << sol.kthSmallest(root, 1) << endl; // Output: 1
return 0;
}
Line Notes
void inorder(TreeNode* node, vector<int>& acc)Helper function to collect nodes inorder
if (!node) return;Stop recursion at null nodes
inorder(node->left, acc);Traverse left subtree first
acc.push_back(node->val);Add current node value after left subtree
return elements[k - 1];Return kth smallest element from sorted vector
int main()Driver code to test the solution
class TreeNode {
constructor(val=0, left=null, right=null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function kthSmallest(root, k) {
const elements = [];
function inorder(node) {
if (!node) return;
inorder(node.left);
elements.push(node.val);
inorder(node.right);
}
inorder(root);
return elements[k - 1];
}
// Driver code
const root = new TreeNode(3);
root.left = new TreeNode(1);
root.right = new TreeNode(4);
root.left.right = new TreeNode(2);
console.log(kthSmallest(root, 1)); // Output: 1
Line Notes
function inorder(node) {Helper function to traverse tree inorder
if (!node) return;Base case to stop recursion
inorder(node.left);Traverse left subtree first
elements.push(node.val);Add current node value after left subtree
return elements[k - 1];Return kth smallest element from sorted array
console.log(kthSmallest(root, 1));Test the function with example input
We visit every node once during inorder traversal, and store all n nodes in a list.
💡 For n=20 nodes, this means about 20 operations to traverse and store, which is manageable but not efficient for very large trees.
Interview Verdict: Accepted but not optimal for large trees
This approach works but uses extra space and time; interviewers expect more efficient solutions.