题目描述
给出一个整数 n,如果 n < 1,代表空树,否则代表中序遍历的结果为 {1, 2, 3… n}。请输出可能的二叉树结构有多少。
输入描述:
第一行输入一个整数 n。
输出描述:
输出一个整数对 1e9 + 7 取模的值表示答案。
示例1
输入
7
输出
429
解法一:动态规划
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
int res = getSum(num);
System.out.println(res);
}
public static int getSum(int num){
if(num<2) return 1;
long[] nums = new long[num+1];
nums[0] = 1;
//动态规划
for(int i=1;i<num+1;i++){
for(int j=1;j<i+1;j++){
nums[i] += nums[j-1]*nums[i-j];
nums[i] %= 1000000007;
}
}
return (int)nums[num]%1000000007;
}
}
解法二:卡特兰数
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
public class Main {
private static final int modNum = (int)1e9 + 7;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.valueOf(in.readLine());
System.out.println(getNumOfTree(n));
}
// 卡特兰数 h(1)=1, h(n) = (4 * n - 2) / (n + 1) * h(n - 1)
// 线性求逆元 inv[i]=-(mod/i)*inv[i%mod]
public static long getNumOfTree(int n) {
long res = 1;
long[] inv = new long[n + 3];
inv[1] = 1;
for(int i = 2; i < n + 3; i++) {
inv[i] = (modNum - modNum / i) * inv[modNum % i] % modNum;
}
for (int i = 0; i < n; i++) {
res = res * ((4 * i + 2) * inv[i + 2] % modNum) % modNum;
}
return res;
}
}
进阶问题:输出所有的树
public List<TreeNode> generate(int n){
return generate(1,n);
}
public List<TreeNode> generate(int start,int end){
List<TreeNode> res = new ArrayList<>();
if(start>end){
res.add(null);
return res;
}
TreeNode head = null;
for(int i=start;i<=end;i++){
head = new TreeNode(i);
List<TreeNode> left = generate(start,i-1);
List<TreeNode> right = generate(i+1,end);
for(TreeNode l:left){
for(TreeNode r:right){
head.left = l;
head.right = r;
res.add(cloneTree(head));
}
}
}
return res;
}
public TreeNode cloneTree(TreeNode head){
if(head==null){
return null;
}
TreeNode newHead = new TreeNode(head.val);
newHead.left = cloneTree(head.left);
newHead.right = cloneTree(head.right);
return newHead;
}