Leecode热题100-230.二叉搜索树中的第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 小的值,你将如何优化算法?

我写的是比较容易想的解法,时间复杂度不一定是最好的,能过就行吧

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**本题使用二叉树的递归套路进行解题,我们需要知道的是左树有多少个节点和右树有多少个节点,这个信息我们定义为info
    然后分别得到左右树这个信息,综合成当前树的信息*/
    public int kthSmallest(TreeNode root, int k) {
        /**获取当前树的info信息 */
        Info info = getInfo(root);
        /**如果左子树的节点数大于等于k了,说明第k大的在左树上,到左树去找 */
        if(info.leftNodes >= k) {
            return kthSmallest(root.left, k);
            /**如果左树节点数+1=k,说明root是第k大的 */
        } else if(info.leftNodes + 1 == k) {
            return root.val;
        } else {
            /**否则到右树上去找,因为左树和根已经有info.leftNodes+1个节点了,所以这里是到右树上找第k - info.leftNodes - 1 */
            return kthSmallest(root.right, k - info.leftNodes - 1);
        }
    }
    /**获取某个节点的Info信息 */
    public Info getInfo(TreeNode root) {
        /**本身是null,info就是null */
        if(root == null) {
            return null;
        }
        /**如果它不为null但是左右孩子都是null,就返回new Info(0,0)*/
        if(root.left == null && root.right == null) {
            return new Info(0,0);
        }
        /**获取左右子树的信息 */
        Info leftInfo = getInfo(root.left);
        Info rightInfo = getInfo(root.right);
        /**根据左右子树的信息获取当前树的info信息 */
        int leftNodes = (leftInfo == null? 0 : leftInfo.leftNodes + leftInfo.rightNodes + 1);
        int rightNodes = (rightInfo == null? 0 : rightInfo.leftNodes + rightInfo.rightNodes + 1);
        return new Info(leftNodes, rightNodes);
    }

    static class Info {
        int leftNodes;
        int rightNodes;
        public Info(int leftNodes, int rightNodes) {
            this.leftNodes = leftNodes;
            this.rightNodes = rightNodes;
        }
    }
}
相关推荐
青 春 记 忆2 小时前
LeetCode 21. 合并两个有序链表|Python 解法详解
python·算法·leetcode·链表
李永奉4 小时前
C语言-嵌入式开发C语言常用预处理指令合集
c语言·开发语言
Sagittarius_A*4 小时前
后量子密码|通识认知 03|量子威胁辟谣:Grover 算法对对称密码的影响与误区
算法·信息安全·密码学·量子计算·pqc·后量子密码
Patrick在香港4 小时前
Python Docker镜像从1.2GB到89MB:多阶段构建的完整优化实录
java·python·docker·信息可视化·容器·数据分析·ai编程
上海安当技术4 小时前
敏感数据怎么防拖库?信封加密(DEK+KEK 二层密钥)架构设计与 Java 实战
java·开发语言·python
我是唐青枫5 小时前
Java JCommander 实战详解:用注解解析命令行参数
java·开发语言
大鹏说大话5 小时前
C++ 内存布局详解:类、虚函数、虚表底层原理
java·开发语言
键盘会跳舞5 小时前
C++:容器适配器 queue 的源码级拆解
开发语言·c++·queue
还是鼠鼠5 小时前
Spring AI连接DeepSeek与通义千问:application.yaml配置详解
java·通义千问·spring ai·deepseek
QAQo7T6 小时前
Python组蓝桥杯备赛超详细知识点总结笔记_排序算法篇
笔记·python·算法·蓝桥杯·排序算法