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.
分治的略繁琐应用。利用BST的性质,左子树范围都比给定的数小,右子树范围比给定的数大,假设当前函数返回给定范围的所有BST,那把所有左子树和右子树都组合一遍就是结果。
root可以是范围内的所有节点.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private List<TreeNode> helper(int start, int end) {
List<TreeNode> roots = new ArrayList<>();
if (start > end) {
return roots;
}
if (start == end) {
roots.add(new TreeNode(start));
return roots;
}
for (int i = start; i <= end; i++) {
TreeNode root;
List<TreeNode> lefts = helper(start, i - 1);
List<TreeNode> rights = helper(i + 1, end);
for (TreeNode left : lefts) {
for (TreeNode right : rights) {
root = new TreeNode(i);
root.left = left;
root.right = right;
roots.add(root);
}
if (rights.isEmpty()) {
root = new TreeNode(i);
root.left = left;
roots.add(root);
}
}
if (lefts.isEmpty()) {
for (TreeNode right : rights) {
root = new TreeNode(i);
root.right = right;
roots.add(root);
}
}
}
return roots;
}
public List<TreeNode> generateTrees(int n) {
return helper(1, n);
}
}
顺着它是在DP求Unique Binary Search Tree I 的思路, i为当前节点个数, j为当前root, 它左子树可以有f[j - 1]种树的形状, 分别就是前面f[j-1]对应生成的树; 右子树有f[i - j - 1]种形状, 它们形状和f[i - j-1]是一样的, 区别在于值, 每个节点相当于f[i - j -1]的树们的每个节点的值加上j + 1这个offset.
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private TreeNode clone(TreeNode node, int offset) {
if (node == null) {
return null;
}
TreeNode newNode = new TreeNode(node.val + offset);
newNode.left = clone(node.left, offset);
newNode.right = clone(node.right, offset);
return newNode;
}
public List<TreeNode> generateTrees(int n) {
List<TreeNode>[] result = new List[n + 1];
result[0] = new ArrayList<TreeNode>();
if (n == 0) {
return result[0];
}
result[0].add(null);
for (int i = 1; i <= n; i++) {
result[i] = new ArrayList<TreeNode>();
for (int j = 0; j < i; j++) {
for (TreeNode nodeL : result[j]) {
for (TreeNode nodeR : result[i - j - 1]) {
TreeNode node = new TreeNode(j + 1);
node.left = nodeL;
node.right = clone(nodeR, j + 1);
result[i].add(node);
}
}
}
}
return result[n];
}
}