给定一个整数 n,生成所有由 1...n 为节点组成的不同的二叉查找树。
例如,
给定 n = 3,则返回所有 5 种不同形态的二叉查找树:
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
他人思路:
参考https://blog.youkuaiyun.com/willduan1/article/details/51615393
首先使用动态规划计算节点从1 到 n 可以构造的 BST 树的个数,接下来使用递归就可以构造一棵 BST 树了,基本思路是 以 i 为根节点,然后 [1, i] 区间构造左子树,[i+1,n] 区间构造右子树,如此不断递归就构造成了一棵完整二叉树。
代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode[] recursion (int s, int e, int[] dp) {
TreeNode[] roots = null;
int curlen = 0;
if (s > e) {
roots = new TreeNode[1];
roots[0] = null;
return roots;
}
roots = new TreeNode[dp[e - s + 1]];
for (int i = s; i <= e; i++) {
TreeNode[] lefts = recursion(s, i - 1, dp); //递归构造左子树
TreeNode[] rights = recursion(i + 1, e, dp); //递归构造右子树
for (TreeNode left : lefts) {
for (TreeNode right : rights) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
roots[curlen++] = root;
}
}
}
return roots;
}
public List<TreeNode> generateTrees(int n) {
if (n == 0) {
return new ArrayList<TreeNode>();
} else {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
TreeNode[] resarr = recursion(1, n, dp);
List<TreeNode> res = new ArrayList<>();
for (TreeNode node : resarr) {
res.add(node);
}
return res;
}
} public TreeNode[] recursion (int s, int e, int[] dp) {
TreeNode[] roots = null;
int curlen = 0;
if (s > e) {
roots = new TreeNode[1];
roots[0] = null;
return roots;
}
roots = new TreeNode[dp[e - s + 1]];
for (int i = s; i <= e; i++) {
TreeNode[] lefts = recursion(s, i - 1, dp); //递归构造左子树
TreeNode[] rights = recursion(i + 1, e, dp); //递归构造右子树
for (TreeNode left : lefts) {
for (TreeNode right : rights) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
roots[curlen++] = root;
}
}
}
return roots;
}
public List<TreeNode> generateTrees(int n) {
if (n == 0) {
return new ArrayList<TreeNode>();
} else {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
TreeNode[] resarr = recursion(1, n, dp);
List<TreeNode> res = new ArrayList<>();
for (TreeNode node : resarr) {
res.add(node);
}
return res;
}
} public TreeNode[] recursion (int s, int e, int[] dp) {
TreeNode[] roots = null;
int curlen = 0;
if (s > e) {
roots = new TreeNode[1];
roots[0] = null;
return roots;
}
roots = new TreeNode[dp[e - s + 1]];
for (int i = s; i <= e; i++) {
TreeNode[] lefts = recursion(s, i - 1, dp); //递归构造左子树
TreeNode[] rights = recursion(i + 1, e, dp); //递归构造右子树
for (TreeNode left : lefts) {
for (TreeNode right : rights) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
roots[curlen++] = root;
}
}
}
return roots;
}
public List<TreeNode> generateTrees(int n) {
if (n == 0) {
return new ArrayList<TreeNode>();
} else {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
TreeNode[] resarr = recursion(1, n, dp);
List<TreeNode> res = new ArrayList<>();
for (TreeNode node : resarr) {
res.add(node);
}
return res;
}
}
}