在某个值范围内生成 BST 的泛型函数

Generic function generating BST over some range of values

本文关键字:BST 泛型 函数 范围内      更新时间:2023-10-16

这个问题与 https://leetcode.com/problems/unique-binary-search-trees-ii 有关

我正在尝试实现一个通用函数,该函数在给定一定范围的连续整数值的情况下生成所有结构上等效的 BST,[m...n]n>=m.这个想法是,如果这个范围的大小(即n-m+1)是相同的,那么无论选择nm,结构上等效的树的数量都应该是相同的。例如,我们可以有(n,m) = (1,9)(n,m) = (5,13),两者的大小均为 9。这两个范围将在结构方面生成相同的 BST,只是值不同。在这种情况下,我们将 1 换成 5,2 换成 6,....,9 换 13,反之亦然。换句话说,在为(n,m) = (1,9)生成所有结构等效的 BST 后,我希望能够使用它轻松地将 [1...9] 中的值交换为 [5...13],而无需重新生成 BST。

所以我想设计一些函数,为一些输入n-m+1生成结构等效的树,存储这些结构等效的 BST,然后能够插入任何n,m并让它给我所有结构等效的节点值在 [n...我不想为将来相同范围大小的输入重新生成 BST。

Leetcode 问题将 BST 节点定义为

struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

如何定义此TreeNode是否可能?它存储的值的类型为int。如果它是类型int *,那么我可以想到一种方法来做到这一点,但当前的定义似乎是有问题的。

这个问题的解决方案具有时间复杂度O(n*Cn)其中Cn是加泰罗尼亚数。无论你如何为子问题创建(或复制或移动)树,你都无法实现更好的复杂性,因为你最终需要打印(比较等)所有树。

您有以下选项:

  1. 按照Hiroki回答的建议创建每棵树的副本。你最终会陷入同样的时间复杂性,你的记忆力会加倍。
  2. 动态修改树值。您可以在树周围创建一个包装函数,val例如

    int getValue(TreeNode* node, int shift){
    return node->val + shift;
    }
    

并在您想要打印所有树时使用此功能。时间复杂度是相同的,您不会为移位的树分配额外的内存。但是,在Leetcode的情况下,这是不可能的,因为平台使用val比较结果,并且您无法将其更改为使用getValue

  1. 更改树的定义并使用int* val。在Leetcode平台上更改结构是不可能的,但让我们也考虑这种情况。如果您为某个范围生成了所有树[1,n]则可以在O(n)中将所有这些树转换为不同的范围。那很好。但是如果你看得更深,你会发现你需要以某种方式使用这些树(例如打印它,遍历它,等等)。所以,你刚刚虚拟地改变了这些树,但最终你最终会再次得到相同的时间复杂度O(n*Cn)。因此,即使有可能,它也没有用。

总结:对于Leetcode平台,您只有选项1.一般来说,您还有其他两个选项,但这3个选项都无法帮助您降低时间复杂度。