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

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

相关推荐
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
weilx12341 天前
C++笔记-文件IO-<fcntl.h>
c++
晨米酱1 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
Smileyqp沛沛1 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·1 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
彧azz1 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
another heaven1 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法