在数学上,二项式系数是二项式定理中各项的系数。以下是关于二项式系数的通常的定义:
1)二项式系数C(n,k)可视为
(
1
+
x
n
)
\left ( 1+ x^{n} \right )
(1+xn)的多项式展开式中,
x
n
x^{n}
xn项的系数。
2)二项式系数C(n,k)还给出了从n个对象中选择k个对象的方式数量。更正式的来说,具有n个元素的集合中包含K个元素的子集的数量。
问题:编写一个只有两个参数n和k,返回二项式系数C(n,k)值的函数。 例如,对于n = 4和k = 2,返回值为6;对于n = 5和k = 2,函数应返回10。
C(n,k)的值可以使用下面的公式递归的求得。
-
C(n, k) = C(n-1, k-1) + C(n-1, k)
-
C(n, 0) = C(n, n) = 1
-
方法一:递归
下面是根据上面的公式求C(n,k)的程序代码:
class BinomialCoefficient {
public int binomialCoeff(int n, int k)
{
// Base Cases
if (k == 0 || k == n)
return 1;
// Recursive
return binomialCoeff(n - 1, k - 1) + binomialCoeff(n - 1, k);
}
}
方法二:使用动态规划
可以注意到,上面的程序一次又一次的计算相同的子问题,为了避免重复的计算,可以考虑建立一个数组c[ ][ ]自底向上的存储之前求得的子问题的值。
class BinomialCoefficient
{
// Returns value of Binomial Coefficient C(n, k)
public int binomialCoeff(int n, int k)
{
int C[][] = new int[n+1][k+1];
int i, j;
// Calculate value of Binomial Coefficient in bottom up manner
for (i = 0; i <= n; i++)
{
for (j = 0; j <= min(i, k); j++)
{
// Base Cases
if (j == 0 || j == i)
C[i][j] = 1;
// Calculate value using previously stored values
else
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
return C[n][k];
}
时间复杂度为: O(n*k)
空间复杂度为: O(n*k)