📌  相关文章
📜  二叉搜索树 (BST) 中给定范围内所有节点的中值(1)

📅  最后修改于: 2023-12-03 15:21:39.814000             🧑  作者: Mango

二叉搜索树 (BST) 中给定范围内所有节点的中值

二叉搜索树 (Binary Search Tree, BST) 是一种二叉树,其中每个节点都包含一个键值,而且节点的键值满足以下两个条件:

  1. 左子树中所有节点的键值小于该节点的键值;
  2. 右子树中所有节点的键值大于该节点的键值。

BST 中常常使用中序遍历(in-order traversal)的方法进行遍历,因为中序遍历会将所有键值按照从小到大的顺序输出。

给定一个 BST 和一个范围 [L, R],求在此范围内所有节点的键值的中值。

算法思路
暴力破解法

我们可以使用中序遍历的方式遍历整个 BST,找到 L 和 R 对应的位置,然后从这个位置开始继续中序遍历,直到达到 R 的位置。在这个过程中,将遍历到的所有节点的键值放到一个数组中,然后对这个数组排序,最后求出这个数组的中值即可。

这种解法的时间复杂度为 O(n log n),其中 n 为 BST 中节点的个数。这是因为对整个数组进行排序所需的时间复杂度为 O(n log n),对 bst 进行遍历的时间复杂度也为 O(n)。

递归法

我们可以使用递归的方式来解决此题。

首先,我们需要想办法缩小搜索范围。根据 BST 的性质,如果当前节点的值小于 L,那么我们就不需要考虑当前节点的左子树,而应该只考虑右子树;反之,如果当前节点的值大于 R,就不需要考虑当前节点的右子树,只考虑左子树。

当当前节点的值在 L 和 R 的范围之内时,我们需要将当前节点的值加入到中值的计算中。由于中值只需要知道所有节点的值的和以及节点的数量,我们可以使用递归函数返回一个 pair 类型的值,其中 pair 的 first 表示所有节点的值的和,second 表示节点的数量。

最后,我们可以用所有节点的值的和除以节点的数量,即可得出所有节点的值的中值。

时间复杂度为 O(n),其中 n 为 BST 中节点的数量,这是由于我们只需要遍历一遍 BST 即可。

代码实现
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    pair<int, int> inorder(TreeNode* root, int L, int R) {
        if (!root) return {0, 0};
        auto left = inorder(root->left, L, R);
        auto right = inorder(root->right, L, R);
        int sum = left.first + right.first + root->val;
        int count = left.second + right.second + 1;
        if (root->val >= L && root->val <= R) {
            return {sum, count};
        } else if (root->val < L) {
            return right;
        } else {
            return left;
        }
    }
    double trimMean(TreeNode* root) {
        auto res = inorder(root, L, R);
        return (double)res.first / res.second;
    }
};

该代码片段使用了 C++ 语言,时间复杂度为 O(n),其中 n 为 BST 中节点的数量。这个程序使用了 pair 类型来保存所有节点的值的和以及节点数量。