LeetCode 95:Unique Binary Search Trees II时间复杂度理解疑问
首先明确结论:官方题解给出的O(n·Cₙ)(Cₙ为第n个卡特兰数)是精确的紧时间复杂度,你提出的O(n·2ⁿ)是一个更宽松的上界,但并非最优(且实际卡特兰数的增长速度比2ⁿ快得多,这个上界也不准确)。下面一步步拆解:
1. 卡特兰数与唯一BST的数量对应关系
n个不同元素能生成的唯一BST总数,恰好等于第n个卡特兰数Cₙ,卡特兰数的递推公式为:
- C₀ = 1(空树的情况)
- Cₙ₊₁ = Σ(Cᵢ · Cₙ₋ᵢ),其中i从0到n
这个递推正好对应BST的生成逻辑:选第i个元素作为根节点,左子树由前i个元素生成(共Cᵢ种可能),右子树由剩余n-i个元素生成(共Cₙ₋ᵢ种可能),所有组合数的总和就是Cₙ₊₁。
2. 递归函数的时间复杂度分析
设f(k)为处理k个连续元素(即递归中r-l+1=k)的时间复杂度:
- 基例:当k=0(空区间)或k=1(单个元素)时,f(k)=O(1)——直接返回固定数量的节点列表,无额外复杂操作。
- 递归情况:当k>1时,我们需要遍历每个元素作为根(共k种选择):
- 递归生成左子树(i-1个元素,时间f(i-1))和右子树(k-i个元素,时间f(k-i));
- 将左子树的所有可能与右子树的所有可能配对,为每对配对创建一个根节点并加入结果列表,这一步的操作数等于左子树数量×右子树数量,即Cᵢ₋₁·Cₖ₋ᵢ。
把这些操作加起来,f(k)的递推式为:f(k) = Σ[f(i-1) + f(k-i) + Cᵢ₋₁·Cₖ₋ᵢ],其中i从1到k
3. 推导精确时间复杂度
根据卡特兰数的定义,Σ(Cᵢ₋₁·Cₖ₋ᵢ)(i=1到k)= Cₖ。
再结合卡特兰数的性质,通过数学归纳法可以证明:f(k) = k·Cₖ。
直观理解也很简单:最终生成的所有BST共有Cₙ个,每个BST包含n个节点,因此整个过程中创建的节点总数是n·Cₙ——而递归过程中最核心的操作就是创建节点,因此时间复杂度就是O(n·Cₙ)。
4. 关于O(n·2ⁿ)的误区
你认为的“每次可选n个根,递归生成左右子树”的思路,错误地假设了子树的数量是2ᵏ级别的,但实际上子树的数量是卡特兰数Cₖ,其渐近增长为Cₙ ≈ 4ⁿ/(n^(3/2)√π),因此n·Cₙ的渐近复杂度是O(4ⁿ/√n),这比O(n·2ⁿ)的增长速度快得多(4ⁿ是2^(2n),指数部分是2n而非n)。所以O(n·2ⁿ)既不是紧界,也没有准确反映实际的增长速度。
内容的提问来源于stack exchange,提问作者Mushahid Nawaz Khan

