给定一个二叉搜索树(BST),找到树中第 K 小的节点

题目:给定一个二叉搜索树(BST),找到树中第 K 小的节点。

* 考察点

  1. 基础数据结构的理解和编码能力
  2. 递归使用

* 示例

       5
      / 
     3   6
    / 
   2   4
  /
 1
 

说明:保证输入的 K 满足 1<=K<=(节点数目)

树相关的题目,第一眼就想到递归求解,左右子树分别遍历。联想到二叉搜索树的性质,root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1,那么 root 就是结果,否则如果左子树节点数目小于 K-1,那么结果必然在右子树,否则就在左子树。因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。

/**
 * Definition for a binary tree node.
 **/

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

class Solution {
    private class ResultType {
    
        boolean found;  // 是否找到
        
        int val;  // 节点数目
        ResultType(boolean found, int val) {
            this.found = found;
            this.val = val;
        }
    }

    public int kthSmallest(TreeNode root, int k) {
        return kthSmallestHelper(root, k).val;
    }

    private ResultType kthSmallestHelper(TreeNode root, int k) {
        if (root == null) {
            return new ResultType(false, 0);
        }

        ResultType left = kthSmallestHelper(root.left, k);

        // 左子树找到,直接返回
        if (left.found) {
            return new ResultType(true, left.val);
        }

        // 左子树的节点数目 = K-1,结果为 root 的值
        if (k - left.val == 1) {
            return new ResultType(true, root.val);
        }

        // 右子树寻找
        ResultType right = kthSmallestHelper(root.right, k - left.val - 1);
        if (right.found) {
            return new ResultType(true, right.val);
        }

        // 没找到,返回节点总数
        return new ResultType(false, left.val + 1 + right.val);
    }
}

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。

说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

示例 1:

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

   3
  / 
 1   4
  
   2


输出: 1


示例 2:

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

       5
      / 
     3   6
    / 
   2   4
  /
 1


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

使用中序遍历

class Solution {
    List<Integer> list = new ArrayList();
    public void dfs(TreeNode root){
        if(root == null)
            return ;
        dfs(root.left);
        list.add(root.val);
        dfs(root.right);
    }
    public int kthSmallest(TreeNode root, int k) {
        dfs(root);
        for(int i=0;i<list.size();i++){
            if(i == k-1)
                return list.get(i);
        }
        return -1;
    }
}


使用递归(计算节点数量):

class Solution {    
    public int count(TreeNode root){
        if(root == null)
            return 0;
        return 1 + count(root.left) + count(root.right);
    }
    public int kthSmallest(TreeNode root, int k) {
        int num = count(root.left);
        if(num == k-1)
            return root.val;
        if(num > k-1)
            return kthSmallest(root.left,k);
        return kthSmallest(root.right,k - num-1);
    }
}


参考链接:

https://blog.csdn.net/xuchonghao/article/details/80770490

https://github.com/debitCrossBlockchain/interview__reference/blob/master/01.%E9%98%BF%E9%87%8C%E7%AF%87/1.1.3%20%E7%BB%99%E5%AE%9A%E4%B8%80%E4%B8%AA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91(BST)%EF%BC%8C%E6%89%BE%E5%88%B0%E6%A0%91%E4%B8%AD%E7%AC%AC%20K%20%E5%B0%8F%E7%9A%84%E8%8A%82%E7%82%B9.md

原文地址:https://www.cnblogs.com/hzcya1995/p/13312574.html