LeetCode:230二叉搜索树中第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 {
    //用于计数和k作比较
    int count = 0;
    //用于返回最终的结果
    int result = -1;

    public int kthSmallest(TreeNode root, int k) {
        inorder(root,k);
        return result;
    }

    public void inorder(TreeNode node, int k){
        if(node == null || count >= k){
            return;
        }

        inorder(node.left,k);
        //计数加1
        count++;
        if(count == k){
            result = node.val;
            return;
        }
        inorder(node.right,k);
    }
}

因为左边的是最小的,我们要找的是从小到大的第k小的元素,所以只有在读取完左边的最小元素后才加1

处理逻辑:

前序遍历:一见到节点就报数,通常用于从上往下的路径搜索

中序遍历:二叉搜索树,从小到大唯一正确的报数时机

后序遍历:通常用于计算高度、深度和销毁树

进阶做法

java 复制代码
//带有 size 属性
class MyTreeNode {
    int val;
    int size; 
    MyTreeNode left;
    MyTreeNode right;
    public MyTreeNode(int val) {
        this.val = val;
        this.size = 1;
    }
}
class Solution {
    // 接收官方的普通树,进行转换
    public int kthSmallest(TreeNode root, int k) {
        // 官方的普通树,转换成带 size 树
        MyTreeNode myRoot = buildTree(root);
        
        return findKth(myRoot, k);
    }

    // TreeNode 转换成 MyTreeNode,并计算 size
    private MyTreeNode buildTree(TreeNode node) {
        if (node == null) return null;
        MyTreeNode myNode = new MyTreeNode(node.val);
        myNode.left = buildTree(node.left);
        myNode.right = buildTree(node.right);
        int leftSize = (myNode.left != null) ? myNode.left.size : 0;
        int rightSize = (myNode.right != null) ? myNode.right.size : 0;
        myNode.size = leftSize + rightSize + 1;
        return myNode;
    }

    //利用 size 找节点
    private int findKth(MyTreeNode curr, int k) {
    
        while (curr != null) {
            // 看看左部分有多少节点
            int leftSize = (curr.left != null) ? curr.left.size : 0;
            
            if (k <= leftSize) {
                // 目标一定在左边
                curr = curr.left;
            } else if (k == leftSize + 1) {
                // 左边刚好排满,当前节点就是我们要找的
                return curr.val;
            } else {
                // 目标在右边,减去当前节点左部分和当前节点的总数,拿着新 k 去右边找
                curr = curr.right;
                k = k - (leftSize + 1);
            }
        }
        return -1;
    }
}

重新定义节点结构,加入size;将原节点转换成带有size的节点,然后进行查找。

相关推荐
qq_4523962332 分钟前
第四篇:《索引原理与实战:B-tree、Hash、GIN、GiST、BRIN》
算法·哈希算法·gin
西索斯coding1 小时前
Qwen3-Max 与 Qwen-Plus:60 个真实修复任务评测方案
大数据·网络·算法·ai
INGNIGHT1 小时前
440 · 背包问题(三)(无限次数)
算法·leetcode·动态规划
suhan1 小时前
【数据结构】七、查找:1.查找的概念、线性结构查找(顺序、折半(二分)、插值、稠密、分块、倒排)
数据结构·算法·排序算法
killerbasd2 小时前
总结 10.26
算法
深圳安锐科技有限公司2 小时前
从成像尺度到亚像素解算:变焦视觉位移监测如何让远近断面都稳
图像处理·人工智能·深度学习·算法·计算机视觉·系统架构·结构健康监测
一只旭宝2 小时前
回调函数(Callback)
linux·服务器·算法
秋名RG2 小时前
算法的划分
算法
Tisfy3 小时前
LeetCode 3619.总价值可以被 K 整除的岛屿数目:广度优先搜索BFS
算法·leetcode·bfs·宽度优先
地平线开发者3 小时前
【大模型】EAGLE 与 EAGLE-3:用“特征预测“加速投机解码
算法