剑指[54]_找出二分搜索树的第K大节点

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指[54]_找出二分搜索树的第K大节点相关的知识,希望对你有一定的参考价值。

题目来源:剑指 Offer 54. 二叉搜索树的第k大节点
题目描述

给定一棵二叉搜索树,请找出其中第k大的节点。

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

限制:

1 ≤ k ≤ 二叉搜索树元素个数;

首先想到的是用中序遍历,因为中序遍历时得到的结果是由小大到的排序;
然后要找第K大的节点,其实就是倒数中序遍历第K大的节点;
但是我刚开始做这道题的时候,想到的是用一个集合来作为辅助结构,把中序遍历的节点值存到集合中,最后再取出(集合的元素个数减去K)那个索引上的节点值;

class TreeNode 
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x)  val = x; 

public class Solution 
    //最终存储中序遍历的集合;
    List<Integer> list = new LinkedList<>();
    public int kthLargest(TreeNode root, int k) 
        if(root == null) throw new RuntimeException("the tree is empty");
        //中序遍历,找索引第(size-k)个即可;
        // 0 1 2 3 4 5 6  size:7 找第5大的,其实索引为2; size - k;
        MiddleOrder(root);
        //找第k大的即可;
        if(k>list.size())
           //要找的索引小于0了,超出限制;
            throw new RuntimeException("Limit Exceeded");
        else 
            return list.get(list.size()-k);
        
    

    //中序遍历;
    private void MiddleOrder(TreeNode root) 
        if(root.left!=null) prefixList(root.left);
        list.add(root.val);
        if(root.right!=null)prefixList(root.right);
    

由于用了额外的空间,效果还是稍差一点;

看过题解,大佬的思路是直接逆向中序遍历;本来中序遍历的结果是由小到大的排序;
逆序的话就是由大到小,直接在逆向的过程中操作;大的元素在前面;
比如下面,想找第4大的节点;每次拿到一节点后,这个指定的K值减一个,继续向前找,直到K值为0时;记录结果;且K值为0时就停止遍历;就返回调用处

class TreeNode 
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x)  val = x; 

public class Solution2 
    //定义返回结果,与指定的k;
    private int result ;
    private int k;
    public int kthLargest(TreeNode root, int k) 
        this.k=k;
        //中序遍历(左中右);反着来(右中左)
        reverMiddleOrder(root);
        return result;
    

    //逆向中序遍历;
    private void reverMiddleOrder(TreeNode root) 
        if(root == null) return;
        //先递归右子树;
        reverMiddleOrder(root.right);
        //当前结点的处理;
        //若目标值已经为0,则返回上一步;(递归要向原调用处返回)
        if(k == 0) return;
        //目标值已为0,返回结果确定;
        if(--k == 0) result = root.val;
        //递归左子树;
        reverMiddleOrder(root.left);
    

以上是关于剑指[54]_找出二分搜索树的第K大节点的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 54. 二叉搜索树的第k大节点

剑指 Offer 54. 二叉搜索树的第k大节点

LeetCode Java刷题笔记—剑指 Offer 54. 二叉搜索树的第k大节点

[LeetCode]剑指 Offer 54. 二叉搜索树的第k大节点

每日一题 - 剑指 Offer 54. 二叉搜索树的第k大节点

⭐算法入门⭐《二叉树 - 二叉搜索树》简单10 —— LeetCode 剑指 Offer 54. 二叉搜索树的第k大节点