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 2, C++ with circular vector
Using a vector of fixed size k and a stack pointer i into it which will be used modulo k.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
vector<TreeNode*> stac(k);
int i = 0, j = k;
while (true) {
while (root) {
stac[i++%k] = root;
root = root->left;
}
root = stac[--i%k];
if (! --j)
return root->val;
root = root->right;
}
}
};
Solution 3, C++ with deque
I really like the previous version, but the fixed size k isn't always necessary, so here's a version using a deque:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
deque<TreeNode*> stac;
while (true) {
while (root) {
stac.push_front(root);
while (stac.size() > k)
stac.pop_back();
root = root->left;
}
root = stac.front();
stac.pop_front();
if (! --k)
return root->val;
root = root->right;
}
}
};
线索
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
TreeNode *left;
int ans;
while (root){
if (root->left){
left = root->left;
while (left->right && left->right != root) left = left->right;
if (left->right == root){
left->right = NULL;
if (--k == 0) ans = root->val; //cannot just return, need to recover the tree
root = root->right;
}else{
if (k <= 0) root = root->right;
else{ // if find the kth, we will not travel new subtree.
left->right = root;
root = root->left;
}
}
}else{
if (--k == 0) ans = root->val;
root = root->right;
}
}
return ans;
}
};
浙公网安备 33010602011771号