1,题目要求
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.
给定二叉搜索树,编写函数kthSmallest以找到其中的第k个最小元素。
注意:
您可以假设k始终有效,1≤k≤BST的总元素。
2,题目思路
对于这道题,要求找到一颗二叉搜索树中第K大的数字。
要想求解这个问题,首先要弄明白二叉搜索树的性质。
对于一颗BST中的某个根节点,其节点左子树中的所有节点的值都比根节点小,右子树中的所有节点的值都比根节点的值要大。
因此,如果对于一个节点而言,左子树中的节点的个数为K-1,那么当前根节点就是第K小的节点。
因此,在算法的实现上,我们只需要对节点的个数进行一个递归/非递归判断即可,唯一需要注意的是,当k的值比左子树中的节点的值+1还要大时,说明我们需要在右子树中进行寻找。
此时,我们要在右子树中寻找第k-count-1小的数字即可。
3,代码实现
方法1:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
int x = []() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
return 0;
}();
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
int count = countNodes(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;
}
private:
int countNodes(TreeNode* root){
if(root == nullptr)
return 0;
return 1 + countNodes(root->left) + countNodes(root->right);
}
};
2,中序遍历-递归
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
count = k;
inorderHelper(root);
return res;
}
private:
int res = 0;
int count = 0;
void inorderHelper(TreeNode* root){
if(root->left!=nullptr)
inorderHelper(root->left);
count--;
if(count == 0){
res = root->val;
return;
}
if(root->right != nullptr)
inorderHelper(root->right);
}
};
3,中序遍历-非递归
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> st;
while(root!=nullptr){
st.push(root);
root = root->left;
}
while(k!=0){
TreeNode *node = st.top();
st.pop();
k--;
if(k == 0)
return node->val;
TreeNode *right = node->right;
while(right != nullptr){
st.push(right);
right = right->left;
}
}
return -1;
}
};