LeetCode 热题 100_二叉搜索树中第 K 小的元素(44_230_中等_C++)(二叉树;中序遍历(递归)+数组;中序遍历(非递归))

LeetCode 热题 100_二叉搜索树中第 K 小的元素(44_230)

题目描述:

给定一个二叉搜索树的根节点 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

题解:

解题思路:

思路一(中序遍历(递归)+数组):

1、因二叉搜索树采用中序遍历的方式遍历的数据是有序且递增的,所以采用递归的中序遍历将结点存储在数组中,再取数组中的第k个元素。

2、复杂度分析:

① 时间复杂度:O(n), n代表树中的节点数,需遍历整个二叉树将结点信息存入数组中所以为O(n),取数组第k个元素的时间为O(1)。

② 空间复杂度:O(n),递归的中序遍历需要 O(logn)~O(n),数组需要存储每个结点的信息O(n)。

思路二(中序遍历(非递归)):

1、在进行非递归中序遍历时,我们可以记录遍历节点的个数,记录的个数来判断当前元素是否是二叉搜索树中第 k 小的元素。当然我们也可以通过遍历一个元素就将k值减小,当k值减小到0时也就是我们要找的元素。

3、复杂度分析

① 时间复杂度:O(k), k代表要取第k小的元素。当我们遍历到第k小的元素时就可以进行返回。

② 空间复杂度:O(n),非递归中序遍历需要栈来存储结点,最坏的情况栈存储n个结点。

代码实现

代码实现(思路一(中序遍历(递归)+数组)):
cpp 复制代码
//方法一(递归):采用中序遍历将结点存储在数组中,再取数组中的第k个元素
int kthSmallest1(TreeNode* root,int k) {
    //nums用于存储中序遍历数据
    vector<int> nums;

    //通过中序遍历将数据存储到nums
    inorder(root,nums);

    //返回第k小的元素
    return nums[k-1];
}
//将元素按中序遍历顺序存入数组nums中
void inorder(TreeNode *root,vector<int> &nums){
    if(root==nullptr) return;
    inorder(root->left,nums);
    nums.emplace_back(root->val);
    inorder(root->right,nums);
}
代码实现(思路二(中序遍历(非递归))):
cpp 复制代码
//方法二(非递归):中序遍历,遍历到第k个时停止
int kthSmallest2(TreeNode *root,int k){
    //判断树是否为空
    if(root==nullptr){
        throw invalid_argument("Tree is empty.");
    }

    stack<TreeNode *> stk;
    while (root!=nullptr||!stk.empty())
    {
        while (root!=nullptr)
        {
            stk.push(root);
            root=root->left;
        }

        root=stk.top();
        stk.pop();
        //每中序遍历访问一个元素将k的值-1,当k=0时正好就是第k小的元素,结束遍历
        --k;
        if(k==0){
            return root->val;
        }

        root=root->right;
    }
    //如果遍历完成也没有找到第k小的元素,则返回异常
    throw out_of_range("k is larger than the number of nodes in the tree.");
}
以思路一完成代码调试
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
{
public:
    //方法一(递归):采用中序遍历将结点存储在数组中,再取数组中的第k个元素
    int kthSmallest1(TreeNode* root,int k) {
        //nums用于存储中序遍历数据
        vector<int> nums;

        //通过中序遍历将数据存储到nums
        inorder(root,nums);

        //返回第k小的元素
        return nums[k-1];
    }
    //将元素按中序遍历顺序存入数组nums中
    void inorder(TreeNode *root,vector<int> &nums){
        if(root==nullptr) return;
        inorder(root->left,nums);
        nums.emplace_back(root->val);
        inorder(root->right,nums);
    }

};



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.kthSmallest1(root,k);

    return 0;
}

LeetCode 热题 100_二叉搜索树中第 K 小的元素(44_230)原题链接

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

相关推荐
码匠许师傅17 分钟前
【C++ 面试真题】聊聊 C++ 的序列容器
java·c++·面试
ValhallaCoder20 分钟前
Leetcode-hot100(2026.08.17)
python·算法·leetcode
C++ 老炮儿的技术栈28 分钟前
Qt5.9.1 Windows 完整开发环境搭建流程
开发语言·c++·windows·qt·编辑器·代码化
泡沫冰@38 分钟前
GO 语言基础
开发语言·算法·golang
键盘会跳舞1 小时前
C++:std::tuple 源码级深度拆解——变参模板、SFINAE与模板元编程核心技巧
开发语言·c++·sfinae·变参模板
bkspiderx1 小时前
从零开始:VS Code搭建C/C++开发环境全指南(Windows/macOS/Linux)
c语言·c++·windows·vs code·c/c++开发环境
东华万里1 小时前
第40篇C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·面试·大学生专区
luj_17682 小时前
元设计的诱惑与现实
c语言·开发语言·c++·经验分享·算法
小星星闪亮登场2 小时前
ST表--倍增思想
开发语言·数据结构·c++·算法·思维
东华万里2 小时前
第40篇 C++核心基础与工程实践:从底层逻辑到避坑指南
开发语言·c++·大学生专区