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;
        }
    }
}
相关推荐
刀法如飞4 分钟前
《理解道德经》简版第5章:天地不仁,以万物为刍狗
面试·机器人
阳明山水7 分钟前
销量预测2025—2026:从模型竞赛到系统融合的范式转型
人工智能·深度学习·算法·机器学习·架构
京师20万禁军教头18 分钟前
47-常用类-八大包装类(Wrapper Classes)
java
come1123424 分钟前
剪映零基础教程
java·linux·运维
16月6日-晴26 分钟前
Java面向对象——接口
java·开发语言
桐盛科技39 分钟前
拒绝“漂绿”风险:基于边缘计算的碳排放数据清洗算法与实时校验逻辑
人工智能·算法·边缘计算
wuyk55540 分钟前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试
geovindu41 分钟前
CSharp: Wordcloud
开发语言·后端·c#·.net·.netcore·词云
-dzk-43 分钟前
【链表】LC 138.随机链表的复制
数据结构·链表
Tongzhi20261 小时前
通芝科技考勤软件三大发展趋势:AI大模型、无感识别与数据底座
大数据·科技·算法·爬山算法