Day84 二叉搜索树中第K小的元素

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/

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

示例1:

	   3
      /  \
    1    4
      \
       2

输入:root = [3,1,4,null,2], k = 1
输出:1

示例2:

          5
        /  \
       3    6
      / \
     2   4
    /
   1

输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3

提示:

树中的节点数为 n 。
1 <= k <= n <= 104
0 <= Node.val <= 104

Java解法

思路:

  • 二叉搜索树的特征:

    节点的左子树只包含小于当前节点的数。

    节点的右子树只包含大于当前节点的数。

    所有左子树和右子树自身必须也是二叉搜索树。

  • 寻找第k小,可以用快慢指针的方式,先对左子树进行遍历,如果左子树所有结点数量小于k,那对右子树进行遍历,同时k-左子树节点数量+根节点1,重复的操作因为无法估量到底的问题,改用栈来存储左子树,弹出时对右子树遍历记数

  • 效率不高,但思路有效

package sj.shimmer.algorithm.m4_2021;

import java.util.Stack;

import sj.shimmer.algorithm.TreeNode;

/**
 * Created by SJ on 2021/4/21.
 */

class D84 {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(
                3,
                new TreeNode(1,null,new TreeNode(2)
                ),
                new TreeNode(4)
                );
        System.out.println(kthSmallest(root,1));
        System.out.println(kthSmallest(root,2));
        System.out.println(kthSmallest(root,3));
        System.out.println(kthSmallest(root,4));
        TreeNode node = TreeNode.getInstance(new Integer[]{5, 3, 6, 2, 4, null, null, 1});
        System.out.println(kthSmallest(node,1));
        System.out.println(kthSmallest(node,2));
        System.out.println(kthSmallest(node,3));
        System.out.println(kthSmallest(node,4));
        System.out.println(kthSmallest(node,5));
        System.out.println(kthSmallest(node,6));
    }
    static int count = 0;
    public static int kthSmallest(TreeNode root, int k) {
        count = k;
        return kthSmallest(root);
    }
    public static int kthSmallest(TreeNode root) {
        //使用栈储找到最小结点的过程
        Stack<TreeNode> stack = new Stack<>();
        TreeNode min = root;
        while (min != null) {
            stack.add(min);
            min =min.left;
        }
        //开始弹出
        while (!stack.isEmpty()&&count>0) {
            TreeNode pop = stack.pop();
            //为当前的最小值
            count--;
            if (count==0) {
                return pop.val;
            }else {
                int result = kthSmallest(pop.right);
                if (result!=-1) {
                    return result;
                }
            }
        }
        return -1;
    }
}

官方解

https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst/solution/er-cha-sou-suo-shu-zhong-di-kxiao-de-yuan-su-by-le/

  1. 遍历树

    深度优先搜索(DFS)
    广度优先搜索(BFS)

    通过中序遍历获取,利用递归形式

    • 时间复杂度:O(N)
    • 空间复杂度:O(N)
  2. 迭代

    类似我的思路,但我比较二,本身用了栈,还死脑筋转去递归了,导致效率上差很多

    public int kthSmallest(TreeNode root, int k) {
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
    
        while (true) {
            while (root != null) {
                stack.add(root);
                root = root.left;
            }
            root = stack.removeLast();
            if (--k == 0) return root.val;
            root = root.right;
        }
    }
    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值