题目描述:输入一个数字,输出所有可能的BST,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
自己完全没思路啊,又是看discuss里一个大佬写的,利用动规;对代码的理解都写在注释中
public static List<TreeNode> generateTrees(int n) {
List<TreeNode>[] lists = new List[n + 1];
lists[0] = new ArrayList<>();
if (n == 0) return lists[0];
//当n=0时不可形成树,为null
lists[0].add(null);
//len是1...n作为lists[]的数组下标,记录1->n个节点树的各种可能
for (int len = 1; len <= n; len++) {
lists[len] = new ArrayList<>();
//以j+1为根节点的树(因为j是从0开始,题目中是从1开始),那么这棵树左子树有j个节点,右子树有len - j -1个节点
//所以这棵树的所有可能是(左子树的种类*右子树的种类)
for (int j = 0; j < len; j++) {
for (TreeNode nodeL : lists[j]) {
for (TreeNode nodeR : lists[len - j - 1]) {
TreeNode node = new TreeNode(j + 1);
//左子树中的值一定都小于j+1,故value不需要改变
node.left = nodeL;
//右子树中的值一定是从1开始一直到len-j-1,所以右子树需要加上j+1
node.right = clone(nodeR, j + 1);
lists[len].add(node);
}
}
}
}
return lists[n];
}
//以递归形式给右子树的node加上j+1
public static TreeNode clone(TreeNode n, int offset) {
if (n == null) return null;
TreeNode node = new TreeNode(n.val + offset);
node.left = clone(n.left, offset);
node.right = clone(n.right, offset);
return node;
}