分治题目:不同的二叉搜索树 II

文章目录

题目

标题和出处

标题:不同的二叉搜索树 II

出处:95. 不同的二叉搜索树 II

难度

5 级

题目描述

要求

给定一个整数 n \texttt{n} n,返回所有由 n \texttt{n} n 个结点组成、结点值从 1 \texttt{1} 1 到 n \texttt{n} n 且结点值各不相同的不同二叉搜索树 。可以按任意顺序返回答案。

示例

示例 1:

输入: n = 3 \texttt{n = 3} n = 3

输出: \[1,null,2,null,3,1,null,3,2,2,1,3,3,1,null,null,2,3,2,null,1] \texttt{\[1,null,2,null,3,1,null,3,2,2,1,3,3,1,null,null,2,3,2,null,1]} \[1,null,2,null,3,1,null,3,2,2,1,3,3,1,null,null,2,3,2,null,1]

示例 2:

输入: n = 1 \texttt{n = 1} n = 1

输出: \[1] \texttt{\[1]} \[1]

数据范围

  • 1 ≤ n ≤ 8 \texttt{1} \le \texttt{n} \le \texttt{8} 1≤n≤8

解法

思路和算法

为了构造二叉搜索树,需要确定二叉搜索树的结点值范围,并确定根结点的值,然后分别构造根结点的左子树和右子树。这是一个递归分治的过程。

由 n n n 个结点组成的二叉搜索树的结点值范围是 1 , n 1, n 1,n。用 rootVal \textit{rootVal} rootVal 表示根结点值,则 1 ≤ rootVal ≤ n 1 \le \textit{rootVal} \le n 1≤rootVal≤n,根结点的左子树的结点值范围是 1 , rootVal − 1 1, \\textit{rootVal} - 1 1,rootVal−1,根结点的右子树的结点值范围是 rootVal + 1 , n \\textit{rootVal} + 1, n rootVal+1,n。对于每个根结点值 rootVal \textit{rootVal} rootVal,其左子树和右子树分别可能有多种情况,根结点的左子树和右子树分别可以是任意一个符合要求的左子树和右子树。

start , end \\textit{start}, \\textit{end} start,end 表示二叉搜索树的结点值范围。分治的终止条件是结点值范围为空,此时符合结点值范围的只有空二叉搜索树 null \text{null} null。当结点值范围不为空时,分别将每个结点值作为根结点值,然后递归地构造左子树和右子树。

当根结点值为 rootVal \textit{rootVal} rootVal 时,用 leftSubtrees \textit{leftSubtrees} leftSubtrees 和 rightSubtrees \textit{rightSubtrees} rightSubtrees 分别表示符合要求的左子树列表和右子树列表,对于任意 leftSubtree ∈ leftSubtrees \textit{leftSubtree} \in \textit{leftSubtrees} leftSubtree∈leftSubtrees 和 rightSubtree ∈ rightSubtrees \textit{rightSubtree} \in \textit{rightSubtrees} rightSubtree∈rightSubtrees,将 leftSubtree \textit{leftSubtree} leftSubtree 和 rightSubtree \textit{rightSubtree} rightSubtree 分别作为根结点的左子树和右子树,即可得到一个符合要求的二叉搜索树。特别地,当 rootVal = 1 \textit{rootVal} = 1 rootVal=1 时必有 leftSubtree = null \textit{leftSubtree} = \text{null} leftSubtree=null,当 rootVal = n \textit{rootVal} = n rootVal=n 时必有 rightSubtree = null \textit{rightSubtree} = \text{null} rightSubtree=null。

代码

java 复制代码
class Solution {
    public List<TreeNode> generateTrees(int n) {
        if (n == 0) {
            return new ArrayList<TreeNode>();
        } else {
            return generateTrees(1, n);
        }
    }

    public List<TreeNode> generateTrees(int start, int end) {
        List<TreeNode> trees = new ArrayList<TreeNode>();
        if (start > end) {
            trees.add(null);
        } else {
            for (int rootVal = start; rootVal <= end; rootVal++) {
                List<TreeNode> leftSubtrees = generateTrees(start, rootVal - 1);
                List<TreeNode> rightSubtrees = generateTrees(rootVal + 1, end);
                for (TreeNode leftSubtree : leftSubtrees) {
                    for (TreeNode rightSubtree : rightSubtrees) {
                        TreeNode root = new TreeNode(rootVal);
                        root.left = leftSubtree;
                        root.right = rightSubtree;
                        trees.add(root);
                    }
                }
            }
        }
        return trees;
    }
}

复杂度分析

  • 时间复杂度: O ( 4 n n ) O(\dfrac{4^n}{\sqrt{n}}) O(n 4n),其中 n n n 是二叉搜索树的结点数。由 n n n 个结点组成的二叉搜索树的数量是第 n n n 个卡特兰数 C 2 n n n + 1 \dfrac{C_{2n}^n}{n + 1} n+1C2nn,其渐进上界为 O ( 4 n n n ) O(\dfrac{4^n}{n \sqrt{n}}) O(nn 4n),对于每个二叉搜索树需要 O ( n ) O(n) O(n) 的时间生成和添加到答案中,因此时间复杂度是 O ( 4 n n ) O(\dfrac{4^n}{\sqrt{n}}) O(n 4n)。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。递归调用栈需要 O ( n ) O(n) O(n) 的空间。注意返回值不计入空间复杂度。

后记

此处提供的解法为分治。由于同一个结点值范围的子树可能被多次计算,因此可以使用记忆化。这道题中的结点数不超过 8 8 8,因此使用记忆化并不能显著提升性能。

读者可以自行尝试使用记忆化的实现。

相关推荐
Tyler_TXZ1 天前
C++C语言之——二叉树
c语言·开发语言·数据结构·c++·二叉树
lingran__7 天前
C++ 高阶数据结构:红黑树万字详解|完整原理推导 + 插入实现 + 完整性校验【STL 底层】
数据结构·c++·面试·红黑树·二叉搜索树·平衡二叉树·stl底层
love_muming7 天前
二叉树操作全解析:从递归到层序遍历
java·数据结构·算法·二叉树
lingran__8 天前
C++ 高阶数据结构:AVL 树万字详解|原理、四种旋转、key‑value 实现、调试校验、set/map/红黑树 底层前置知识
数据结构·c++·二叉搜索树·平衡二叉树·avl树·红黑树前置
-dzk-9 天前
【二叉树】LC 101.对称二叉树
算法·二叉树
bnmoel15 天前
数据结构深度剖析二叉树・下篇:链式结构的实现 ,遍历方法全解析
c语言·数据结构·算法·二叉树·
星马梦缘15 天前
算法设计导论 课堂笔记
算法·动态规划·分治·时间复杂度·最优二叉树
stolentime23 天前
SP8549 MAIN75 - BST again题解
c++·算法·二叉树·深度优先·图论·记忆化搜索·组合数学
bu_shuo1 个月前
计算机二级公共知识学习-树和二叉树
二叉树··中序遍历·后序遍历·计算机二级·先序遍历