Problem
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.
Example 1:
Input: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
Output: 3
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?
Solution
Binary Search
class Solution {
public int kthSmallest(TreeNode root, int k) {
int countLeft = count(root.left);
if (k <= countLeft) return kthSmallest(root.left, k);
else if (k > countLeft+1) return kthSmallest(root.right, k-countLeft-1);
else return root.val; //k == countLeft+1
}
private int count(TreeNode root) {
int count = 0;
if (root == null) return count;
return count(root.left)+1+count(root.right);
}
}
In-Order Traversal Iteration
class Solution {
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> stack = new ArrayDeque<>();
while (root != null) {
stack.push(root);
root = root.left;
}
while (k != 0) {
TreeNode node = stack.pop();
k--;
if (k == 0) return node.val;
TreeNode cur = node.right;
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
}
return -1;
}
}
In-Order Traversal Recursion
class Solution {
int res = 0;
int count = 0;
public int kthSmallest(TreeNode root, int k) {
count = k;
helper(root);
return res;
}
private void helper(TreeNode root) {
if (root == null) return;
helper(root.left);
count--;
if (count == 0) res = root.val;
helper(root.right);
}
}