力扣刷题:二叉搜索树中第K小的元素(java实现)

题目:给定一个二叉搜索树的根节点 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 <= 10^4
  • 0 <= Node.val <= 10^4

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

相关标签:深度优先搜索二叉搜索树二叉树

解析:
搜索二叉树介绍:二叉查找树(英语:Binary Search Tree),也称为有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;

二叉搜索树有一个非常重要的特性:二叉搜索树的中序遍历结果一定是有序的。
按照这个特性,可以使用二叉树的中序遍历算法来实现。
方法一:迭代法(二叉树的中序遍历)

public int kthSmallest(TreeNode root, int k) {
        //定义一个栈来维护遍历过的结点,先入后出
        Stack<TreeNode> stack = new Stack<>();
        //标记结点的索引,初始是1。(因为第k个是从1开始数的)
        int sign = 1;
        while (!stack.isEmpty()||root!=null){
            if(root!=null){
                //如果当前结点不是空,就入栈,知道找到最左的结点
                stack.push(root);
                root = root.left;
            }else {
                //当前结点是空,说明上一个结点就是最左结点
                root = stack.pop();
                if(k == sign ){
                    //当前结点就是答案
                    return root.val;
                }else {
                    sign++;
                }
                //说明当前root结点以及左子数的都不是第k小的
                //这时遍历右子树
                root = root.right;
            }
        }
        return 0;
    }

方法二:递归法。
大概思路:因为搜索二叉树的中序遍历一定是排序的,而且是从小到大。如果左子树的结点个数比k大,说明要找的结点在左边。如果左子树的结点个数+1等于k,说明根节点就是要找的结点,同理如果k大于左边结点个数+1,就在右边。
具体代码如下所示:

public int kthSmallest(TreeNode root, int k) {
        //获取左子树的结点数量
        int left = getNodeNumber(root.left);
        //如果左子树结点数量大于k,说明要找的就在左边
        if(left>=k){
            //如果左子树的结点个数大于k,说明第k小在左子树
            return kthSmallest(root.left,k);
        }else if(left+1==k){
            //如果左子树结点个数+1等于k,说明根节点就是要找的结点
            return root.val;
        }else {
            //如果左子树结点个数+1小于k,说明要找的结点在右子树
            return kthSmallest(root.right,k-left-1);
        }
    }
    //获取二叉树结点个数的方法
    public int getNodeNumber(TreeNode treeNode){
        if(treeNode==null){
            return 0;
        }
        return 1+getNodeNumber(treeNode.left)+getNodeNumber(treeNode.right);
    }

看到这里
别卷了,休息会儿吧~

  • 18
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谦谦均

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值