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

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

相关推荐
胖大和尚8 分钟前
在C++的类中,是否可以把函数声明成__device__
c++·cuda
十年磨剑走天涯15 分钟前
C++ STL 容器操作复杂度速查表
开发语言·c++
Hi李耶24 分钟前
【LeetCode】6-Z字形变换
算法·leetcode·职场和发展
ziguo112225 分钟前
Windows API MessageBox 函数详解
c语言·c++·windows·visualstudio
王老师青少年编程29 分钟前
2023年CSP-J初赛真题及答案解析(11-15)
c++·真题·csp-j·答案·csp·初赛·信奥赛
15Moonlight31 分钟前
C++进阶(09):特殊类设计
开发语言·c++
AKA__Zas44 分钟前
芝士算法(前缀和2.0)
java·数据结构·算法·leetcode·哈希算法·学习方法
皓月斯语1 小时前
B3867 [GESP202309 三级] 小杨的储蓄 题解
c++·算法·题解
choumin1 小时前
行为型模式——模板方法模式
c++·设计模式·模板方法模式·行为型模式