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. 你真的会玩SQL吗?EXISTS和IN之间的区别

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  2. react入门(3)

    在第一篇文章里我们介绍了jsx.组件.css写法  点击查看react入门(1) 第二篇文章里我们介绍了事件.this.props.children.props....other.map循环  点击查 ...

  3. Spark 入门

    Spark 入门 目录 一. 1. 2. 3. 二. 三. 1. 2. 3. (1) (2) (3) 4. 5. 四. 1. 2. 3. 4. 5. 五.         Spark Shell使用 ...

  4. NopCommerce 在Category 显示Vendor List列表

    实现效果如下: 1.在前台Web的Category Menu显示 Vendor; 2.点击Vendor 显示Vendor List列表: 主要配置步骤: 1.运行网站 Admin 后台   Categ ...

  5. 【C#公共帮助类】 WebHelper帮助类

    如果你是一个新手,如果你刚接触MVC,如果你跟着置顶的那个项目,我们肯定会用到这里面的几个帮助类 它们都在Common类库下,大家一定要记住要点:取其精华去其糟粕,切勿拿来主义~ Applicatio ...

  6. openresty 前端开发序

    还记得第一次尝试前后端分离的时候,是使用nginx + react 构建的spa应用,后端是java,主要处理业务逻辑逻辑部分,返回json数据,在nginx里面配置好html + js纯静态文件,再 ...

  7. SpringMVC启动过程详解(li)

    通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...

  8. LAMP布署笔记

    源代码软件的优点:     获得最新版,能及时修复bug:     能自行修改和定制: 源代码打包形式:     .tar.gz和.tar.bz2格式居多: 完整性校验:     md5sum校验工具 ...

  9. CSS3和javascript中的transform

    在javascript中,WebkitTransform 大概相当于 transform .transform 为标准,WebkitTransform 适用于Webkit浏览器.js中的WebkitT ...

  10. 实现一个基于 SharePoint 2013 的 Timecard 应用(中)

    门户视图 随着 Timecard 列表的增多,如何查找和管理这许多的 Timecard 也就成了问题.尤其对于团队经理而言,他除了自己填写的 Timecard,还要审核团队成员的 Timecard 任 ...