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

相关推荐
wuyk5554 分钟前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
pen-ai43 分钟前
【优化方法】最小二乘:从误差平方到线性与非线性拟合
人工智能·算法·机器学习
Q26433650232 小时前
【有源码】基于机器学习的电信网络诈骗话术语义识别与可视化分析系统 XGBoost算法+Hadoop+Spark
大数据·hadoop·算法·机器学习·spark·毕业设计·课程设计
不会就选b2 小时前
算法日常・每日刷题--贪心<11>
算法·leetcode·职场和发展
千里码aicood2 小时前
面向电商冷启动与数据稀疏性的协同过滤算法优化研究
大数据·算法·协同过滤
xxxiugou1232 小时前
双指针解题秘籍:从入门到精通
c语言·数据结构·c++·算法
能源革命2 小时前
TimesFM(Time Series Foundation Model)介绍
算法·能源
猎嘤一号2 小时前
学术训练(一)文献检索与阅读
人工智能·算法·机器学习·科研入门
Doubbbbbbble云2 小时前
多路归并算法在外部排序中的实现与优化
算法
沉淀的.晴天2 小时前
FreeRTOS信号量
数据结构·算法