Given a binary search tree, write a function kthSmallest
to find the kth smallest element in it.
Note:
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
Hint:
- Try to utilize the property of a BST.
- What if you could modify the BST node's structure?
- The optimal runtime complexity is O(height of BST).
Solution 1
public static int kthSmallest(TreeNode root, int k) {
int count = count(root.left);
if(k <= count){
return kthSmallest(root.left, k);
}else if(k > count + 1){
return kthSmallest(root.right, k-1-count);
}
return root.val;
}
public static int count(TreeNode root){
if(root == null){
return 0;
}
return 1 + count(root.left) + count(root.right);
}
Solution 2
private static int number = 0;
private static int count = 0;
public int kthSmallest2(TreeNode root, int k) {
count = k;
helper(root);
return number;
}
public void helper(TreeNode n) {
if (n.left != null) helper(n.left);
count--;
if (count == 0) {
number = n.val;
return;
}
if (n.right != null) helper(n.right);
}
Solution 3
//Iterative
public int kthSmallest3(TreeNode root, int k) {
Stack<TreeNode> st = new Stack<>();
while (root != null) {
st.push(root);
root = root.left;
}
while (k != 0) {
TreeNode n = st.pop();
k--;
if (k == 0) return n.val;
TreeNode right = n.right;
while (right != null) {
st.push(right);
right = right.left;
}
}
return -1; // never hit if k is valid
}
Solution 4 Revise the TreeNode structure