二叉搜索树中第K小的元素
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
输出: 1
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
输出: 3
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?
思路:
方法1:
- 遍历二叉树。
- 维护一个大小为k的大顶堆。
方法2:
深度优先,中序遍历即可得到一个升序的数组,返回nums[k-1]即可。
各种遍历方法参考链接1。
方法3:
我们从根延伸到某一片叶子,然后再返回另一个分支。
在栈的帮助下,可以将方法一的递归转换为迭代,这样可以加快速度,因为这样可以不用遍历整个树,可以在找到答案后停止。
代码:
方法1:
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
//维护一个大小为k的大顶堆
priority_queue<int, vector<int>, less<int>> big_q;
int count=0;
queue<TreeNode*> q;
q.push(root);
TreeNode* cur_node;
while(!q.empty())
{
cur_node=q.front();
q.pop();
if(cur_node->left)
{
q.push(cur_node->left);
}
if(cur_node->right)
{
q.push(cur_node->right);
}
if(count++<k)
{
big_q.push(cur_node->val);
}else{
if(cur_node->val<big_q.top())
{
big_q.pop();
big_q.push(cur_node->val);
}
}
}
return big_q.top();
}
};
方法2:
class Solution {
public:
vector<int> nums;
void inorderTrava(TreeNode* root) //中序遍历
{
if(!root)
return ;
inorderTrava(root->left);
nums.emplace_back(root->val);
inorderTrava(root->right);
}
int kthSmallest(TreeNode* root, int k) {
inorderTrava( root);
return nums[k-1];
}
};
方法3:
int kthSmallest(TreeNode* root, int k)
{
stack<TreeNode*> st;
while(1)
{
while(root)
{
st.push(root);
root=root->left;
}
root=st.top();
st.pop();
k-=1;
if(!k)
return root->val;
root=root->right;
}
return 0;
}
结果:
方法1:
方法2:
方法3:
参考链接:
[1] 消失男孩:[C/C++]二叉树遍历与恢复
[2] 力扣 (LeetCode):二叉搜索树中第K小的元素