个人学习之用,如果有看客觉得哪里不清楚或者有错误,欢迎指出,会尽量及时更新。
算法
卡特兰数 Catalan Number
卡特兰数可用下式算出(法1)
卡特兰数递推式(法2) 卡特兰数是符合以下公式的数列
上式推导方法参见96. 不同的二叉搜索树,首先可以注意到本题相当于满足编号中序遍历为1-n的二叉树的个数,又相当于n个相同点组成二叉树的个数。
做法是DP,集合为n个点时不同的二叉搜索树,属性为数量,sum 左右子树的可能种数之积。
卡特兰数适用的问题
- 相同 n 个点组成的不同二叉树的个数
- 中序遍历为 1-n 的二叉树的个数
- 节点值为 1-n 的二叉搜索树的个数
- n对( )的合法组合(栈)
- n个0,n个1,条件:任何前缀中0的个数不少于1的个数
- 1, 2, ···, n 合法的进栈出栈序列的个数
- 不同的操作序列 -> 不同的排列
所以卡特兰数可以转化为求组合数的问题
补充:杨辉三角
// n 比较小的时候,杨辉三角,递推 O(n^2)
// n 在10e5 质数 乘法逆元 O(nlogn)
// n 在10e18 lucas 定理
// 高精度 阶乘分解
最简单的方法,用Python和java写,方便解决大数。
n = int(input())
# catalan number: C_2n^n/(n+1) 所以要2*n
C = [[0]*(2*n+1) for _ in range(2*n+1)]
for i in range(0, 2*n+1):
for j in range(0, i+1):
if not j:
C[i][j] = 1
else:
C[i][j] = C[i-1][j] + C[i-1][j-1]
print(C[2*n][n]//(n+1))