Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.

Example:

Input: 3
Output:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below: 1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3

这道题是之前的 Unique Binary Search Trees 的延伸,之前那个只要求算出所有不同的二叉搜索树的个数,这道题让把那些二叉树都建立出来。这种建树问题一般来说都是用递归来解,这道题也不例外,划分左右子树,递归构造。这个其实是用到了大名鼎鼎的分治法 Divide and Conquer,类似的题目还有之前的那道 Different Ways to Add Parentheses 用的方法一样,用递归来解,划分左右两个子数组,递归构造。刚开始时,将区间 [1, n] 当作一个整体,然后需要将其中的每个数字都当作根结点,其划分开了左右两个子区间,然后分别调用递归函数,会得到两个结点数组,接下来要做的就是从这两个数组中每次各取一个结点,当作当前根结点的左右子结点,然后将根结点加入结果 res 数组中即可,参见代码如下:

解法一:

class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == ) return {};
return helper(, n);
}
vector<TreeNode*> helper(int start, int end) {
if (start > end) return {nullptr};
vector<TreeNode*> res;
for (int i = start; i <= end; ++i) {
auto left = helper(start, i - ), right = helper(i + , end);
for (auto a : left) {
for (auto b : right) {
TreeNode *node = new TreeNode(i);
node->left = a;
node->right = b;
res.push_back(node);
}
}
}
return res;
}
};

我们可以使用记忆数组来优化,保存计算过的中间结果,从而避免重复计算。注意这道题的标签有一个是动态规划 Dynamic Programming,其实带记忆数组的递归形式就是 DP 的一种,memo[i][j] 表示在区间 [i, j] 范围内可以生成的所有 BST 的根结点,所以 memo 必须是一个三维数组,这样在递归函数中,就可以去 memo 中查找当前的区间是否已经计算过了,是的话,直接返回 memo 中的数组,否则就按之前的方法去计算,最后计算好了之后要更新 memo 数组,参见代码如下:

解法二:

class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == ) return {};
vector<vector<vector<TreeNode*>>> memo(n, vector<vector<TreeNode*>>(n));
return helper(, n, memo);
}
vector<TreeNode*> helper(int start, int end, vector<vector<vector<TreeNode*>>>& memo) {
if (start > end) return {nullptr};
if (!memo[start - ][end - ].empty()) return memo[start - ][end - ];
vector<TreeNode*> res;
for (int i = start; i <= end; ++i) {
auto left = helper(start, i - , memo), right = helper(i + , end, memo);
for (auto a : left) {
for (auto b : right) {
TreeNode *node = new TreeNode(i);
node->left = a;
node->right = b;
res.push_back(node);
}
}
}
return memo[start - ][end - ] = res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/95

类似题目:

Unique Binary Search Trees

Different Ways to Add Parentheses

参考资料:

https://leetcode.com/problems/unique-binary-search-trees-ii/

https://leetcode.com/problems/unique-binary-search-trees-ii/discuss/31494/A-simple-recursive-solution

https://leetcode.com/problems/unique-binary-search-trees-ii/discuss/31535/20ms-C%2B%2B-top-down-DP-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Unique Binary Search Trees II 独一无二的二叉搜索树之二的更多相关文章

  1. LeetCode: Unique Binary Search Trees II 解题报告

    Unique Binary Search Trees II Given n, generate all structurally unique BST's (binary search trees) ...

  2. [LeetCode] 95. Unique Binary Search Trees II 独一无二的二叉搜索树之二

    Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ...

  3. LeetCode - Unique Binary Search Trees II

    题目: Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. F ...

  4. [Leetcode] Unique binary search trees ii 唯一二叉搜索树

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  5. LeetCode——Unique Binary Search Trees II

    Question Given an integer n, generate all structurally unique BST's (binary search trees) that store ...

  6. [LeetCode] Unique Binary Search Trees II dfs 深度搜索

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...

  7. [leetcode]Unique Binary Search Trees II @ Python

    原题地址:https://oj.leetcode.com/problems/unique-binary-search-trees-ii/ 题意:接上一题,这题要求返回的是所有符合条件的二叉查找树,而上 ...

  8. LeetCode:Unique Binary Search Trees I II

    LeetCode:Unique Binary Search Trees Given n, how many structurally unique BST's (binary search trees ...

  9. [LeetCode] Unique Binary Search Trees 独一无二的二叉搜索树

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

随机推荐

  1. 虚拟IP(VIP)

    高可用性HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性.HA系统是目前企业防止核心计算机系统因故 ...

  2. 【那些年关于java多态应用】

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal { public abstract void Say();} 子类: public class ...

  3. [Asp.net 5] Caching-缓存架构与源码分析

    首先奉献caching的开源地址[微软源码] 1.工程架构 为了提高程序效率,我们经常将一些不频繁修改,但是使用了还很大的数据进行缓存.尤其是互联网产品,缓存可以说是提升效率优化第一利器.微软为我们实 ...

  4. BZOJ3095 : 二元组

    \[\begin{eqnarray*}&&\sum_{i=0}^{n-1}\left(ki+b-a_i\right)^2\\&=&\sum_{i=0}^{n-1}\le ...

  5. spring源码:web容器启动(li)

    web项目中可以集成spring的ApplicationContext进行bean的管理,这样使用起来bean更加便捷,能够利用到很多spring的特性.我们比较常用的web容器有jetty,tomc ...

  6. CentOS6.7搭建LNMP环境

    1:查看环境: [root@localhost ~]# cat /etc/redhat-release 2:关掉防火墙 #重启后生效开启 [root@localhost ~]# chkconfig i ...

  7. js判断网页是否加载完毕 包括图片

    <script type="text/javascript" language="JavaScript"> //: 判断网页是否加载完成 docum ...

  8. ubuntu自动执行

    一般先写个sh脚本文件---->要执行的语句写入sh文件----->chromd -x ???.sh增加权限即可 crontab -e * * * * * /home/???.sh */1 ...

  9. SQL Server快速查询某张表的当前行数

    传统做法可能是select count(1) 但是往往会比较慢.推荐如下做法: ) CurrentRowCount FROM sys.sysindexes WHERE id = OBJECT_ID(' ...

  10. Java中serialVersionUID的解释及两种生成方式的区别(转载)

    转载自:http://blog.csdn.net/xuanxiaochuan/article/details/25052057 serialVersionUID作用:        序列化时为了保持版 ...