第一种 : 给定一个数值 n 求它能构成的不同的BST的个数:
这类题,很像那个求斐波那契和,关键就是把状态记录
通过一个数组 把 1 到 i 的BST数目记录 , : 范围大小相等,那么BST的数目一样,接下来就可以直接利用了!
public class Solution {
public int numTrees(int n) {
int[] num = new int[n + 1];
num[0] = 1;
for (int i = 1 ; i <= n ; i++) { // 1 到i构建BST
int count = 0;
for (int j = 1 ; j <= i ; j++) {//哪一个为根节点
int left = j - 1; // 左子树的节点个数
int right = i - j; // 右子树的节点个数
count += (num[left] * num[right]);
}
num[i] = count;
}
return num[n];
}
}
第二种类型 : 要求的不是不同BST的个数,而是把每一棵BST列出来。
这个题目,开始的时候卡在了右子树该怎么表示那块了!!
总的来说,这个题目的思路,就是通过一个列表来存储之前数值相对应的子树,只要要表示的数值范围相同,那么子树的形状都是一样,
比如123 和 456!!!
// 1234 那么当root = 3, left = 2 root = 4 left = 3 ,我想,用一个map把对应的范围内的树存起来,用的时候在来取
// 比如把 12 的可能情况存起来,求123的BST,root=3的话,就直接可以用12的了?但是一个问题root = 1? 或者 123456 ,root = 3
// 456怎么办!!这道题目的精华就在这里了!!前面那种解法是没有错的,即通过一个链表来存放各个值对应的树!但要表示456 ,相对应的
// 就只要把123 的值+3不就等于456了吗!!!!
public List<TreeNode> generateTrees(int n) {
Map<Integer , List<TreeNode>> map = new HashMap<> (); // 每个值对应的树
List<TreeNode> l = new ArrayList<>();
// put 0
l.add(null);
if(n < 1) return l;
map.put(0,l); // 0
// put 1
l = new LinkedList<TreeNode>();
TreeNode root = new TreeNode(1);
l.add(root);
map.put(1, l);
for(int i = 2 ; i <= n ; i++) { // 1 到 n 1234567
List<TreeNode> list = new ArrayList<>();
// TreeNode node = new TreeNode(i); // 加入 i = 7
for(int j = 1 ; j <= i ; j++) { // 1到i中哪一个值为顶点
List<TreeNode> left = map.get(j - 1); // 6 5 4 3 2 1 0
List<TreeNode> right = map.get(i - j); //0 1 2 3 4 5 6
for (TreeNode ln : left) {
for (TreeNode rn : right) {
TreeNode node = new TreeNode(j); //注意这一块,你不能在上面那个for循环定义TreeNode ,或者更上层,因为这里每一个treeNode对应着的就是一颗新的树
node.left = ln; // 你如果在外层循环中定义,这不会乱套了吗。
node.right = copyToRight(rn , j); //右子树的节点 就需要把左子树中相同数目的子树 的 节点 + add!
list.add(node);
}
}
}
map.put(i , list);
}
return map.get(n);
}
// 只要节点的数目相同,那么他们子树形状都是一样,我们接下来要的就是遍历树,对每个节点 val + add
public TreeNode copyToRight(TreeNode node , int add) {
if(node == null) return node;
TreeNode n = new TreeNode (node.val + add);
n.left = copyToRight(node.left , add);
n.right = copyToRight(node.right , add);
return n;
}
}