LeetCode 算法:二叉搜索树中第K小的元素 c++

原题链接🔗:二叉搜索树中第K小的元素
难度:中等⭐️⭐️

题目

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

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

题解

二叉搜索树

二叉搜索树(Binary Search Tree,简称BST)是一种特殊的二叉树,它具有以下性质:

  1. 有序性:对于树中的每个节点,其左子树上所有节点的值都小于该节点的值,其右子树上所有节点的值都大于或等于该节点的值。

  2. 没有兄弟节点:每个节点最多只有一个左子节点和一个右子节点。

  3. 每个节点存储一个键值:在二叉搜索树中,每个节点通常存储一个键值,该键值用于维护树的有序性。

  4. 树结构:二叉搜索树是树结构,这意味着它是一个没有环的分层数据结构。

  5. 平衡性:理想情况下,二叉搜索树是平衡的,即左右子树的高度差不超过1。平衡的二叉搜索树可以保证操作(如搜索、插入和删除)的时间复杂度为O(log n)。但在最坏的情况下,如果插入的元素是有序的,树将退化成链表,时间复杂度变为O(n)。

二叉搜索树的应用非常广泛,因为它提供了高效的数据存储和检索方式。以下是一些基本操作:

  • 搜索:在BST中搜索一个元素,可以从头节点开始,根据目标值与当前节点值的比较结果,决定是向左子树还是向右子树搜索。这个过程可以递归或迭代进行,直到找到目标值或到达叶子节点。

  • 插入:向BST中插入一个新元素,首先搜索该元素应该插入的位置,然后根据BST的性质将其插入到适当的位置。

  • 删除:从BST中删除一个元素,需要考虑几种情况:删除的节点没有子节点、有一个子节点或有两个子节点。在删除节点后,需要调整树以保持BST的性质。

  • 遍历:BST可以通过前序、中序、后序和层序遍历来访问所有节点。中序遍历特别有用,因为它将按照升序访问所有节点。

二叉搜索树的实现通常涉及到递归和迭代技术,以及对树结构的深入理解。在实际应用中,为了提高性能,可能会使用自平衡的二叉搜索树,如AVL树或红黑树。

中序遍历

二叉树的中序遍历是一种遍历二叉树的方法,其遍历顺序为:先遍历左子树,然后访问根节点,最后遍历右子树。这种遍历方式可以确保在访问任何节点之前,其所有左子节点已经被访问过,同样地,在访问任何节点之后,其所有右子节点也会被访问。

中序遍历对于二叉搜索树(BST)特别有用,因为它会按照节点值的非递减顺序访问所有节点,即中序遍历的结果是一个有序数组。

以下是中序遍历的基本步骤:

  1. 访问左子树:首先,递归地对左子树进行中序遍历。

  2. 访问根节点:然后,访问根节点。在遍历过程中,通常会将根节点的值添加到一个列表中。

  3. 访问右子树:最后,递归地对右子树进行中序遍历。

中序遍历的时间复杂度为O(n),其中n是树中节点的数量,因为它需要访问树中的每个节点。空间复杂度取决于递归调用的深度,最坏情况下是O(n)(当树退化成链表时),最好情况下是O(log
n)(当树是平衡的)。

中序遍历递归法

  1. 解题思路

在LeetCode上,题目“二叉搜索树中第K小的元素”通常要求你找到一个二叉搜索树(BST)中第K小的元素。二叉搜索树的性质是:对于树中的任何节点,其左子树上的所有节点的值都小于该节点的值,其右子树上的所有节点的值都大于该节点的值。

解题思路如下:

  • 理解BST的性质:首先,要利用BST的性质来简化问题。在BST中,中序遍历(左-根-右)会以递增的顺序访问所有节点。

  • 中序遍历:由于题目要求找到第K小的元素,我们可以通过中序遍历BST来实现。在遍历过程中,记录访问的节点数量。

  • 计数与停止:在中序遍历的过程中,当访问到第K个节点时,停止遍历。这个节点就是所求的第K小的元素。

  • 递归或迭代:中序遍历可以通过递归或迭代的方式实现。递归是更直观的方法,但迭代可以避免潜在的递归深度问题。

  • 实现算法:编写代码实现上述逻辑。

  1. c++ demo
#include <iostream>
#include <vector>

// 定义二叉树的节点结构
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

class Solution {
public:
    // 主函数,接收二叉搜索树的根节点和K值,返回第K小的元素
    int kthSmallest(TreeNode* root, int k) {
        std::vector<int> elements;
        inOrderTraversal(root, elements, k);
        return elements[k - 1]; // 由于数组索引从0开始,所以用k-1
    }

private:
    // 中序遍历辅助函数,同时接收一个vector来存储遍历结果
    void inOrderTraversal(TreeNode* node, std::vector<int>& elements, int k) {
        if (!node || elements.size() >= k) {
            return;
        }

        // 遍历左子树
        inOrderTraversal(node->left, elements, k);

        // 访问当前节点
        if (elements.size() < k) {
            elements.push_back(node->val);
        }

        // 遍历右子树
        inOrderTraversal(node->right, elements, k);
    }
};

// 示例使用
int main() {
    // 构建一个示例二叉搜索树
    //       3
    //      / \
    //     1   4
    //      \
    //       2
    TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(1);
    root->right = new TreeNode(4);
    root->left->right = new TreeNode(2);

    Solution solution;
    int k = 3; // 假设我们要找第3小的元素
    std::cout << "The " << k << "st smallest element is: " << solution.kthSmallest(root, k) << std::endl;

    // 清理分配的内存(在实际应用中应该使用智能指针来自动管理内存)
    delete root->left->right;
    delete root->left;
    delete root->right;
    delete root;

    return 0;
}
  • 输出结果:

The 3st smallest element is: 3

  1. 代码仓库地址:kthSmallest

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/759230.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【web】2、集成插件

1、element-plus 官网地址:设计 | Element Plus 安装 plus 及 icon 图标库 1.1 官网提供plus安装方法&#xff1a; 1.2 官网提供 icon 安装方法 1.3 安装 pnpm install element-plus element-plus/icons-vue main.ts全局安装element-plus,element-plus默认支持语言英语设…

Navicat 外网连接 mysql (1、通过SSH方式内网访问 2、对外开放3306端口)

1、通过SSH方式内网访问 直接常规方式使用IP、账号密码连接&#xff0c;失败 SSH方式&#xff1a; 常规 选项卡中&#xff1a;localhost录入数据库账号密码 SSH 选项卡中&#xff1a;勾选使用SSH&#xff0c;输入服务器IP、账号、密码 如果出现该错误&#xff0c;可能是服务器…

51个图表,完美展示数据分布关系!

本节介绍seaborn展示数据分布关系的图表&#xff08;Distribution plots&#xff09;的实现&#xff0c;该类图表用于展示数据集的分布规律&#xff0c;帮助快速获取数据多方面信息&#xff0c;例如&#xff0c;观测值的范围、中心趋势、是否存在某个方向上严重偏斜、是否存在双…

10大内网安全管理系统!企业内网安全必备系统

内网安全管理系统对于维护企业网络安全至关重要&#xff0c;它们帮助监控、管理内部网络资源&#xff0c;防止数据泄露和安全威胁。以下是十款知名的内网安全管理系统。 1. 安企神终端安全管理系统 详细介绍&#xff1a; 安企神是针对企业内网安全需求设计的一款综合管理系统&…

在大数据盛行的今天,为什么需要使用图数据库?

分类 性能 可扩展性 灵活性 复杂性 键值存储数据库 高 高 高 无 文档数据库 高 可变 高 低 列存储数据库 高 可变 一般 低 图数据库 可变 高 高 高 关系型数据库 可变 可变 低 一般 表1&#xff1a;5类主流数据库产品分析 对于深度数据的分析和…

数值分析笔记(四)数值微积分

牛顿-科茨公式 ∫ a b f ( x ) d x ≈ ( b − a ) ∑ k 0 n C k ( n ) f ( a k h ) \int_a^bf(x) \mathrm{d}x\approx(b-a)\sum_{k0}^nC_k^{(n)}f(akh) ∫ab​f(x)dx≈(b−a)k0∑n​Ck(n)​f(akh) 其中&#xff0c; C k ( n ) C_k^{(n)} Ck(n)​为科茨系数。 n1时&#xff…

Drag Select Compose:实现多平台图片多选功能的利器

Drag Select Compose:实现多平台图片多选功能的利器 在现代移动应用开发中,图片多选功能是一个常见且实用的需求。而实现这种功能可能涉及到复杂的手势处理和状态管理。今天,我将介绍一款强大的Compose多平台库——Drag Select Compose,它能够轻松实现类似于Google Photos…

Qt开发 | 无边框窗口 | 自定义标题栏 | 拖拽拉伸 | 窗口阴影 | 圆角窗口

文章目录 一、QWidget类介绍二、无边框窗口的基本实现三、自定义标题栏并实现拖拽拉伸四、设计一个无边框窗口公共类五、标题栏qss美化、关闭、最小化、最大化六、实现窗口阴影七、圆角窗口八、一个自定义标题栏带圆角阴影的窗口 一、QWidget类介绍 QWidget 是 Qt 框架中的一个…

SpringBoot整合MongoDB JPA使用

一、整合MongoDB SpringDataMongoDB是 SpringData家族成员之一&#xff0c;MongoDB的持久层框架&#xff0c;底层封装了 mongodb-driver。mongodb-driver 是 MongoDB官方推出的 Java连接 MongoDB的驱动包&#xff0c;相当于JDBC驱动。 SpringBoot整合 MongoDB&#xff0c;引入…

【MySQL】数据库——备份与恢复,日志管理1

一、数据备份的重要性 1.备份的主要目的是灾难恢复 在生产环境中&#xff0c;数据的安全性至关重要 任何数据的丢失都可能产生严重的后果造成数据丢失的原因&#xff1a; 程序错误人为,操作错误运算错误磁盘故障灾难&#xff08;如火灾、地震&#xff09;和盗窃 2.数据库备份…

pcap包常见拆分方法

文章目录 Wireshark 拆分流量包SplitCap使用简介魔数报错示例结果 在进行流量分析时&#xff0c;经常需要分析pcap流量包。但是体积过大的流量包不容易直接分析&#xff0c;经常需要按照一定的规则把它拆分成小的数据包。 这里统一选择cic数据集里的Thursday-WorkingHours.pcap…

【Oracle篇】逻辑备份工具expdp(exp)/impdp(imp)和物理备份工具rman的区别和各自的使用场景总汇(第八篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

基于局域网下的服务器连接、文件传输以及内网穿透教程 | 服务器连接ssh | 服务器文件传输scp | 内网穿透frp | 研究生入学必备 | 深度学习必备

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;本篇博客分享的是基于局域网下的服务器连接&#x1f517;、文件传输以及内网穿透教程&#xff0c;内容非常完备✨&#xff0c;涵盖了在服务器上做深度学…

目标检测常用涨点方法:注意力机制小结(空间注意力、通道注意力、CBAM等)

1.通道注意力 通道注意力&#xff08;Channel Attention&#xff09;是在通道维度上对输入数据进行学习&#xff0c;再对不同的通道分配相应的权重表示重要性&#xff0c;从而达到“分配注意力”的效果。SENet&#xff08;Squeeze and Excitation networks) 是一个典型的使用通…

J020_二分查找算法

一、查找过程 使用二分查找算法有一个必要的前提&#xff1a;数组已经是一个排好序的数组。 以下面数组为例&#xff0c;讲述二分查找过程&#xff1a; 二、代码实现 package com.itheima.sort;public class BinarySearch {public static void main(String[] args) {int[] a…

STM32第十三课:DMA多通道采集光照烟雾

文章目录 需求一、DMA&#xff08;直接存储器存取&#xff09;二、实现流程1.时钟使能2.设置外设寄存器地址3.设置存储器地址4.设置要传输的数据量5.设置通道优先级6.设置传输方向7.使通道和ADC转换 三、数据处理四、需求实现总结 需求 通过DMA实现光照强度和烟雾浓度的多通道…

VQVAE:Neural Discrete Representation Learning

论文名称&#xff1a;Neural Discrete Representation Learning 开源地址 发表时间&#xff1a;NIPS2017 作者及组织&#xff1a;Aaron van den Oord,Oriol Vinyals和Koray Kavukcuoglu, 来自DeepMind。 1、VAE 简单回顾下VAE的损失函数&#xff0c;ELBO的下界为&#xff1a; …

单晶层状氧化物制作方法技术资料 纳离子技术

网盘 https://pan.baidu.com/s/1hjHsXvTXG74-0fDo5TtXWQ?pwd10jk 单晶型高熵普鲁士蓝正极材料及其制备方法与应用.pdf 厘米级铬氧化物单晶及其制备方法和存储器件.pdf 多孔氧化物单晶材料及其制备方法和应用.pdf 大单晶层状氧化物正极材料及其制备方法和应用.pdf 富钠P2相层状…

3DMAX折纸插件FoldPoly使用方法详解

3DMAX折纸插件FoldPoly使用教程 3DMAX折纸插件FoldPoly&#xff0c;用于挤出可编辑多边形的边&#xff08;边界&#xff09;并可旋转&#xff08;折叠&#xff09;新生成的面&#xff0c;创建类似手工折纸以及纸箱包装盒的建模效果。 【版本要求】 3dMax2014 - 2025&#xff…

线性代数|机器学习-P20鞍点和极值

文章目录 1 . 瑞利商的思考1.1 瑞利商的定义1.2 投影向量 2. 拉格朗日乘子法3. 鞍点 1 . 瑞利商的思考 1.1 瑞利商的定义 假设A是n阶实对称矩阵&#xff0c;x是n维非零列向量&#xff0c;那么瑞利商表示如下&#xff1a; R ( A , x ) x T A x x T x \begin{equation} R(A,x…