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?
s思路:
1. bst. kth最小的话,那就是in-order遍历当计数器等于k就找到了,复杂度是o(n)
2. 如果经常修改,那么可以给每个把每个节点左右子树的节点个数作为一个member放在每个节点的private里面,就省事了,直接查询!用binary search即可
3.
//方法1:in-order, iterative,套路做法
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
//
stack<TreeNode*> ss;
TreeNode* cur=root;
while(cur||!ss.empty()){
while(cur){
ss.push(cur);
cur=cur->left;
}
cur=ss.top();
ss.pop();
if(--k==0) return cur->val;
cur=cur->right;
}
return 0;
}
};
//方法2:in-order, recursive,不套路,值得学习
//刚想的时候,还不晓得如何操作k,由于是in-order,所以就在操作根的时候--k即可!
class Solution {
public:
void helper(TreeNode* root,int&k,int&res){
if(!root) return;
helper(root->left,k,res);//先左
if(--k==0){//再根
res=root->val;
return;
}
helper(root->right,k,res);//后右
}
int kthSmallest(TreeNode* root, int k) {
//
int res=0;
helper(root,k,res);
return res;
}
};
//方法3:binary search:但复杂度为o(nlgn)
class Solution {
public:
int count(TreeNode* root){
if(!root) return 0;
return 1+count(root->left)+count(root->right);
}
int kthSmallest(TreeNode* root, int k) {
//
int left=count(root->left);
if(left+1>k){
return kthSmallest(root->left,k);
}else if(left+1<k){
return kthSmallest(root->right,k-left-1);
}
return root->val;
}
};