You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

卡特兰数乘积求和计算的性能优化问询

卡特兰数递推计算的性能优化方案

看起来你已经在尝试优化卡特兰数递推计算的性能了,从缓存卡特兰数的思路就能看出来找对方向了!针对你遇到的n增大后性能急剧下降的问题,结合你的现有代码,给你几个更深入的优化方向:

1. 用递推式直接生成缓存,彻底避免组合数重复计算

你当前的缓存方案还是依赖catalan(i)通过组合数计算每个卡特兰数,而组合数本身的循环计算在n较大时会带来大量重复开销。其实完全可以基于卡特兰数的递推定义直接生成缓存数组,用已经计算好的前序项来推导后续项:

// 初始化缓存数组,要计算C_{n+1},所以数组长度设为n+2
BigInteger[] catalans = new BigInteger[n + 2];
catalans[0] = BigInteger.ONE;
if (n >= 1) {
    catalans[1] = BigInteger.ONE;
}

// 递推生成前n+1项卡特兰数
for (int i = 2; i <= n + 1; i++) {
    BigInteger sum = BigInteger.ZERO;
    for (int j = 0; j < i; j++) {
        sum = sum.add(catalans[j].multiply(catalans[i - 1 - j]));
    }
    catalans[i] = sum;
}

// 直接得到目标值C_{n+1}
BigInteger catalanSum = catalans[n + 1];

这种方式完全绕开了组合数计算的额外开销,所有计算都基于已缓存的结果,性能提升非常明显。

2. 利用对称性减少一半计算量

你在编辑2里提出的思路非常正确!卡特兰数满足对称性吗?不,其实是递推式中的乘积项具有对称性:对于任意i,$C_i * C_{n-i}$ 和 $C_{n-i} * C_i$ 的结果完全相同,我们只需要计算前半部分的乘积,再乘以2,最后处理中间的特殊项即可:

BigInteger catalanSum = BigInteger.ZERO;
int mid = n / 2;
// 计算前半部分的乘积,每一项乘2
for (int i = 0; i < mid; i++) {
    BigInteger product = catalans[i].multiply(catalans[n - i]);
    catalanSum = catalanSum.add(product.multiply(BigInteger.TWO));
}
// 当n为偶数时,中间项i=mid,此时n-i=mid,乘积是C_mid的平方,单独加上
if (n % 2 == 0) {
    catalanSum = catalanSum.add(catalans[mid].multiply(catalans[mid]));
}

这样循环次数直接从n+1次减少到$\lfloor n/2 \rfloor$次,对于大n来说,计算量直接减半,性能提升立竿见影。

3. 合并缓存生成与目标计算,避免额外循环

我们可以把缓存生成和$C_{n+1}$的计算合并成一个循环,不需要先单独生成所有卡特兰数再循环求和,进一步减少冗余操作:

BigInteger[] catalans = new BigInteger[n + 2];
catalans[0] = BigInteger.ONE;
if (n >= 1) {
    catalans[1] = BigInteger.ONE;
}

for (int i = 2; i <= n + 1; i++) {
    BigInteger sum = BigInteger.ZERO;
    int half = i / 2;
    // 利用对称性计算当前项的和
    for (int j = 0; j < half; j++) {
        sum = sum.add(catalans[j].multiply(catalans[i - 1 - j]).multiply(BigInteger.TWO));
    }
    // 处理中间项
    if (i % 2 == 1) {
        int mid = (i - 1) / 2;
        sum = sum.add(catalans[mid].multiply(catalans[mid]));
    }
    catalans[i] = sum;
}

BigInteger catalanSum = catalans[n + 1];

这个版本把对称性优化直接融入到递推过程中,一步到位生成所有需要的卡特兰数,同时得到目标结果,没有任何额外的循环开销。


内容的提问来源于stack exchange,提问作者acGunner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:12:17