LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230_C++_中等)

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)原题链接

欢迎大家和我沟通交流(✿◠‿◠)

相关推荐
hh随便起个名4 小时前
力扣二叉树的三种遍历
javascript·数据结构·算法·leetcode
橘子真甜~4 小时前
C/C++ Linux网络编程15 - 网络层IP协议
linux·网络·c++·网络协议·tcp/ip·计算机网络·网络层
写写闲篇儿4 小时前
微软面试之白板做题
面试·职场和发展
敲敲了个代码5 小时前
隐式类型转换:哈基米 == 猫 ? true :false
开发语言·前端·javascript·学习·面试·web
asiwxy6 小时前
OpenGL 材质
c++
阿华hhh6 小时前
Linux系统编程(标准io)
linux·开发语言·c++
liang_jy6 小时前
Android LaunchMode
android·面试
LYFlied6 小时前
【每日算法】LeetCode 17. 电话号码的字母组合
前端·算法·leetcode·面试·职场和发展
程序喵大人6 小时前
推荐个 C++ 练习平台
开发语言·c++·工具推荐
fpcc7 小时前
跟我学C++中级篇——std::is_invocable的分析应
c++