第一种 : 给定一个数值 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; } }