当前位置: 首页 > news >正文

LeetCode 热题 100 230. 二叉搜索树中第 K 小的元素

LeetCode 热题 100 | 230. 二叉搜索树中第 K 小的元素

大家好,今天我们来解决一道经典的二叉搜索树问题——二叉搜索树中第 K 小的元素。这道题在 LeetCode 上被标记为中等难度,要求查找二叉搜索树中的第 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 <= 10^4
  • 0 <= Node.val <= 10^4

解题思路

方法一:中序遍历(递归)
  1. 初步分析

    • 二叉搜索树(BST)的中序遍历可以得到一个有序的节点值序列。
    • 因此,使用中序遍历可以找到二叉搜索树中的第 K 小的元素。
  2. 步骤

    • 递归进行中序遍历,遍历到第 K 个元素时返回其值。
  3. 代码实现

class Solution:def kthSmallest(self, root: TreeNode, k: int) -> int:self.count = 0self.result = 0def travel(t):if t is None:returntravel(t.left)  # 左self.count += 1  # 中if self.count == k:self.result = t.valtravel(t.right)  # 右travel(root)return self.result
方法二:中序遍历(迭代)
  1. 初步分析

    • 如果不想使用递归,可以使用显式栈来模拟中序遍历。
    • 遍历到第 K 个元素时返回其值。
  2. 步骤

    • 使用栈模拟中序遍历,通过栈记录每次访问的节点。
  3. 代码实现

class Solution:def kthSmallest(self, root: TreeNode, k: int) -> int:stack = []current = rootwhile current or stack:while current:stack.append(current)current = current.leftcurrent = stack.pop()k -= 1if k == 0:return current.valcurrent = current.right
方法三:基于分治的优化
  1. 初步分析

    • 通过计算每个节点的左子树节点数,可以在 O(log n) 的时间复杂度内找到第 K 小的元素。
    • 如果 K 小于左子树的节点数,则在左子树中查找;如果 K 等于左子树的节点数 + 1,则当前节点即为第 K 小的元素;否则在右子树中查找。
  2. 步骤

    • 计算每个节点的左子树节点数,根据 K 的值决定在左子树还是右子树查找。
  3. 代码实现

class Solution:def kthSmallest(self, root: TreeNode, k: int) -> int:def countNodes(node):if not node:return 0return 1 + countNodes(node.left) + countNodes(node.right)left_count = countNodes(root.left)if k <= left_count:return self.kthSmallest(root.left, k)elif k > left_count + 1:return self.kthSmallest(root.right, k - left_count - 1)else:return root.val

复杂度分析

  • 时间复杂度

    • 中序遍历(递归和迭代):O(n),其中 n 是二叉搜索树的节点数。需要遍历整个树。
    • 基于分治的优化方法:O(log n) 到 O(n),最坏情况下需要遍历整个树,但在平衡树中可以在 O(log n) 内完成查找。
  • 空间复杂度

    • 中序遍历(递归):O(n),用于递归调用栈。
    • 中序遍历(迭代):O(n),用于存储栈的额外空间。
    • 基于分治的优化方法:O(h),其中 h 是树的高度,递归调用栈的深度等于树的高度。

进阶问题

如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 K 小的值,可以考虑以下优化方法:

  1. 使用自平衡的二叉搜索树

    • 使用 AVL 树或红黑树,可以保证树的高度最小化,从而使得查找、插入和删除操作的时间复杂度为 O(log n)。
  2. 维护子树大小信息

    • 在每个节点上维护两个额外的信息:左子树中的节点数(称为“左序”)和右子树中的节点数(称为“右序”)。每次插入或删除操作后,更新这些统计信息。利用节点的左序和右序信息,可以在不完全遍历树的情况下找到第 K 小的节点。

总结

通过中序遍历的方法,我们可以高效地找到二叉搜索树中的第 K 小的元素。基于分治的优化方法可以在平衡树中进一步提高查找效率。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!

关注我,获取更多算法题解和编程技巧!

相关文章:

  • Apollo学习——键盘控制速度
  • 白盒测试——基本路径测试法
  • 【网络协议】TCP、HTTP、MQTT 和 WebSocket 对比
  • uni-app vue3版本打包h5后 页面跳转报错(uni[e] is not a function)
  • Lighthouse 自定义审计
  • SpringAI更新:废弃tools方法、正式支持DeepSeek!
  • Linux `whoami` 命令深度解析与高阶应用指南
  • “强强联手,智启未来”凯创未来与绿算技术共筑高端智能家居及智能照明领域新生态
  • 《Python星球日记》 第72天:问答系统与信息检索
  • 一文介绍电路交换、报文交换和分组交换
  • 给 DBGridEh 增加勾选用的检查框 CheckBox
  • Qt笔记---》.pro中配置
  • Java项目拷打(外卖+点评)
  • Java大师成长计划之第22天:Spring Cloud微服务架构
  • 软考 系统架构设计师系列知识点之杂项集萃(59)
  • 计算机组成原理:I/O
  • 论MCU如何在Fatfs中使用Flash接口的方法
  • TCP/IP参考模型详解:从理论架构到实战应用
  • 【Java】 volatile 和 synchronized 的比较及使用场景
  • matlab插值方法(简短)
  • 3年多来俄乌要首次直接对话?能谈得拢吗?
  • A股午后拉升,沪指收复3400点:大金融发力,两市成交超1.3万亿元
  • 美国明尼苏达州发生山火,过火面积超80平方公里
  • 通化市委书记孙简升任吉林省副省长
  • 尹锡悦涉嫌发动内乱案举行第三次庭审
  • 让“五颜六色”面孔讲述上海故事,2025年上海城市推荐官开启选拔