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;
        }
    }
}
相关推荐
JD技术委员会几秒前
Rust 语法噪音这么多,是否适合复杂项目?
开发语言·人工智能·rust
tekin2 分钟前
Go、Java、Python、C/C++、PHP、Rust 语言全方位对比分析
java·c++·golang·编程语言对比·python 语言·php 语言·编程适用场景
Hello.Reader4 分钟前
Rust 中的 `Drop` 特性:自动化资源清理的魔法
开发语言·rust·自动化
liruiqiang055 分钟前
机器学习 - 投票感知器
人工智能·算法·机器学习
Vitalia7 分钟前
从零开始学 Rust:基本概念——变量、数据类型、函数、控制流
开发语言·后端·rust
小禾苗_1 小时前
C++ ——继承
开发语言·c++
李长渊哦1 小时前
Java 虚拟机(JVM)方法区详解
java·开发语言·jvm
进击ing小白1 小时前
Qt程序退出相关资源释放问题
开发语言·qt
烂蜻蜓2 小时前
前端已死?什么是前端
开发语言·前端·javascript·vue.js·uni-app
老猿讲编程2 小时前
安全C语言编码规范概述
c语言·开发语言·安全