LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230_C++_中等)
题目描述:
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。
输入输出样例:
示例 1:

输入 :root = [3,1,4,null,2], k = 1
输出:1
示例 2:

输入 :root = [5,3,6,2,4,null,null,1], k = 3
输出 :3
提示:
树中的节点数为 n 。
1 <= k <= n <= 104
0 <= Node.val <= 104
题解:
解题思路:
思路一(中序遍历:DFS):
1、因此树为二叉搜索树,所以可以中序遍历为有序,可以方便的找到第 K 小的元素。在遍历的过程中记录遍历的个数,直至遍历到第 k 个结点则返回。
2、复杂度分析:
① 时间复杂度:O(k),, k代表要取第k小的元素。当我们遍历到第k小的元素时就可以进行返回。
② 空间复杂度:O(n),n为二叉搜索树中结点的个数,最坏的情况下,递归的深度为n。
其他思路
其他思路可查看此链接:LeetCode 热题 100_二叉搜索树中第 K 小的元素(44_230)
代码实现
代码实现(思路一(中序遍历:DFS)):
cpp
class Solution {
private:
int n = 0; // 记录当前访问到的节点的顺序
int ans = -1; // 用于保存第 k 小的元素
// 中序遍历的递归函数
void inorder(TreeNode* root, int k) {
// 如果当前节点为空或者已经找到了第 k 小的元素,则返回
if (root == nullptr || ans != -1) {
return;
}
// 递归遍历左子树
inorder(root->left, k);
// 访问当前节点,更新节点顺序
n++;
// 如果当前节点是第 k 小的元素,记录答案
if (n == k) {
ans = root->val;
}
// 递归遍历右子树
inorder(root->right, k);
}
public:
// 主函数,调用中序遍历并返回结果
int kthSmallest(TreeNode* root, int k) {
inorder(root, k); // 调用中序遍历函数
return ans; // 返回第 k 小的元素
}
};
以思路一为例进行调试
cpp
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode():val(0),left(nullptr),right(nullptr){}
TreeNode(int x):val(x),left(nullptr),right(nullptr){}
TreeNode(int x,TreeNode *left,TreeNode *right):val(x),left(left),right(right){}
};
//通过数组创建二叉树(数组元素为-1代表nullptr)
TreeNode *creatTree(vector<int> nums){
if(nums.empty()) return nullptr;
TreeNode *root=new TreeNode(nums[0]);
queue<TreeNode *> q;
q.push(root);
int i=1;
while (i<nums.size())
{
TreeNode *node=q.front();
q.pop();
if(i<nums.size()&&nums[i]!=-1){
node->left=new TreeNode(nums[i]);
q.push(node->left);
}
++i;
if(i<nums.size()&&nums[i]!=-1){
node->right=new TreeNode(nums[i]);
q.push(node->right);
}
++i;
}
return root;
}
//中序遍历输出二叉树(用于验证二叉树是否创建成功)
void inorder_print(TreeNode *root){
if(root==nullptr) return ;
inorder_print(root->left);
cout<<root->val<<" ";
inorder_print(root->right);
}
class Solution {
private:
int n = 0; // 记录当前访问到的节点的顺序
int ans = -1; // 用于保存第 k 小的元素
// 中序遍历的递归函数
void inorder(TreeNode* root, int k) {
// 如果当前节点为空或者已经找到了第 k 小的元素,则返回
if (root == nullptr || ans != -1) {
return;
}
// 递归遍历左子树
inorder(root->left, k);
// 访问当前节点,更新节点顺序
n++;
// 如果当前节点是第 k 小的元素,记录答案
if (n == k) {
ans = root->val;
}
// 递归遍历右子树
inorder(root->right, k);
}
public:
// 主函数,调用中序遍历并返回结果
int kthSmallest(TreeNode* root, int k) {
inorder(root, k); // 调用中序遍历函数
return ans; // 返回第 k 小的元素
}
};
int main(){
vector<int> nums={3,1,4,-1,2};
//通过数组创建二叉树
TreeNode *root=creatTree(nums);
//中序遍历输出二叉搜索树(验证二叉搜索树创建是否正确)
//inorder_print(root);
//搜索二叉树中第k小的元素并输出
Solution s;
int k=1;
cout<<s.kthSmallest(root,k);
return 0;
}
LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230)原题链接
欢迎大家和我沟通交流(✿◠‿◠)