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的节点,然后进行查找。

相关推荐
我命由我1234511 小时前
人脸识别 - 人脸识别选帧
java·人工智能·python·算法·安全·java-ee·人脸识别
时针滴滴答啊11 小时前
最大子数组和
算法·leetcode·职场和发展
五月底_12 小时前
LIS算法
python·算法·最长子序列
学学酱快乐12 小时前
2026年PMP考试生命周期选择决策树精讲:从需求判断到混合型统一框架的应试全攻略
算法·决策树·机器学习·pmp新版考试大纲·pmp新题型·pmp培训哪家好·pmp培训机构推荐
傅科摆 _ py12 小时前
动态规划复习
算法·动态规划
Wang's Blog13 小时前
PostgreSQL笔记49:向量检索核心算法、索引调优与过滤策略深度解析
笔记·算法·postgresql
疯狂打码的少年13 小时前
【数据结构】交换类排序:冒泡与快速排序
数据结构·笔记·算法·排序算法
Nil20814 小时前
leetcode 108有序数组转换为二叉搜索树
数据结构·算法·leetcode
高频因子挖掘机14 小时前
QuantDash 成交量单位统一实战:从“手”到“股”的跨市场量化数据清洗全流程
后端·算法·github
hn小菜鸡14 小时前
LeetCode 763、划分字母区间
数据结构·算法·leetcode