【题目】
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.
【思路】
BST的特点就是排序性,左边的节点一定比root小,右边的节点一定比root大。
另外就是二分性。
找第k个,可以先看左边树节点的个数,小于k的话,就保证了肯定是在右边。那么去找右边的k-left.
k - left,就变成了新的k.
数root所在的树的节点数。这个就是用递归实现。想法就是,如果root自己本身就是null,那么就return 0; 否则至少+1,是自己,然后 自己+ 左孩子的数目 + 右孩子的数目!
【代码】
三种方法!!也是大神阿~
Binary search:
public int kthSmallest(TreeNode root, int k) {
int count = countNodes(root.left);
if (k <= count) {
return kthSmallest(root.left, k);
<span style="background-color: rgb(255, 255, 102);">} else if (k > count + 1) {
return kthSmallest(root.right, k-1-count); // 1 is counted as current node</span>
}
return root.val;
}
public int countNodes(TreeNode n) {
if (n == null) return 0;
return 1 + countNodes(n.left) + countNodes(n.right);
}
DFS:
// better keep these two variables in a wrapper class
private static int number = 0;
private static int count = 0;
public int kthSmallest(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);
}
BFS :
public int kthSmallest(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
}