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] 95. Unique Binary Search Trees II 独一无二的二叉搜索树之二的更多相关文章

  1. [LeetCode] 95. Unique Binary Search Trees II(给定一个数字n,返回所有二叉搜索树) ☆☆☆

    Unique Binary Search Trees II leetcode java [LeetCode]Unique Binary Search Trees II 异构二叉查找树II Unique ...

  2. [leetcode]95. Unique Binary Search Trees II给定节点形成不同BST的集合

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

  3. [LeetCode] 95. Unique Binary Search Trees II 唯一二叉搜索树 II

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

  4. leetcode 95 Unique Binary Search Trees II ----- java

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

  5. leetCode 95.Unique Binary Search Trees II (唯一二叉搜索树) 解题思路和方法

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

  6. [leetcode]95 Unique Binary Search Trees II (Medium)

    原题 字母题添加链接描述 一开始完全没有思路.. 百度看了别人的思路,对于这种递归构造的题目还是不熟,得多做做了. 这个题目难在构造出来.一般构造树都需要递归. 从1–n中任意选择一个数当做根节点,所 ...

  7. LeetCode 95. Unique Binary Search Trees II 动态演示

    比如输入为n, 这道题目就是让返回由1,2,... n的组成的所有二叉排序树,每个树都必须包含这n个数 这是二叉树的排列组合的题目.排列组合经常用DFS来解决. 这道题比如输入为3,也就是求start ...

  8. 【LeetCode】95. Unique Binary Search Trees II 解题报告(Python)

    [LeetCode]95. Unique Binary Search Trees II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzh ...

  9. leetcode 96. Unique Binary Search Trees 、95. Unique Binary Search Trees II 、241. Different Ways to Add Parentheses

    96. Unique Binary Search Trees https://www.cnblogs.com/grandyang/p/4299608.html 3由dp[1]*dp[1].dp[0]* ...

随机推荐

  1. openssl编译安装

    最新版本可以在这个网站下载: https://www.openssl.org/source/ wget https://www.openssl.org/source/openssl-1.1.1c.ta ...

  2. sklearn 学习 第一篇:分类

    分类属于监督学习算法,是指根据已有的数据和标签(分类)进行学习,预测未知数据的标签.分类问题的目标是预测数据的类别标签(class label),可以把分类问题划分为二分类和多分类问题.二分类是指在两 ...

  3. UWP 推荐 - 限时免费的RSS阅读器《RSS 追踪》登录 Windows 10

    文/云之幻 前不久,博客作者 Bravo Yeung 写了一篇还算略受欢迎的关于 RSS 的文章 .Net开发者必知的技术类RSS订阅指南. RSS 现在用的人很少了,而且就算是我,也不过是在一周前才 ...

  4. C++回调,函数指针

    想要理解回调机制,先要理解函数指针 函数指针 函数指针指向的是函数而非对象,和其他指针一样,函数指针指向某种特定的类型 函数的类型由他的返回类型和参数类型共同决定,与函数名无关,如: bool len ...

  5. c# "As" 与 "Is"效率 (原发布csdn 2017-10-07 11:49:18)

    十一长假就要过去了,今年假期没有回家,一个人闲着无聊就在看C#语言规范5.0中文版.昨天看了 is运算符和 as运算符,平时项目中也有用到这两种符号,对于其效率也没有进行比较过,趁着假期有空,先看下效 ...

  6. navicat 连接 mysql 出现Client does not support authentication protocol requested by server解决方案

    安装了navicat 和 mysql,结果最后在navicat中连接mysql时,出现了如下错误提示: Client does not support authentication protocol ...

  7. tkinter为多个窗口设置相同的icon报错

    import threading import tkinter from PIL import Image, ImageTk def show_window(): window = tkinter.T ...

  8. 软件工程个人作业(wc.exe项目)

    一.项目Github地址 https://github.com/huangzihaohzh/WordCounter 二.PSP表格 PSP2.1 Personal Software Process S ...

  9. bat脚本里面if else if的写法

    曾经困扰了很久的bat脚本,如果里面包含多种条件判断,就必须要试用if,else if,else的写法了.尝试了很久,终于找到规律: 第一种写法:最简单,就是写一行. @echo off rem 写一 ...

  10. 源码详解Pytorch的state_dict和load_state_dict

    在 Pytorch 中一种模型保存和加载的方式如下: # save torch.save(model.state_dict(), PATH) # load model = MyModel(*args, ...