如何计算二项式系数时间和空间复杂度? (迭代与递归)

时间:2017-10-06 16:26:41

标签: c++ algorithm time-complexity space-complexity

这是迭代版本,但它调用递归函数。这会对其时间/空间复杂性产生影响吗?

int factorial(int n) {
    if (n == 1) {
        return 1;
    }
    else {
        return n * factorial(n - 1);
    }
}

int binomial_coefficient_iterative(unsigned int n, unsigned int k) {
    if (k == 0 || k == n) {
        return 1;
    }
    else {
        return (factorial(n) / ( factorial(k) * factorial(n - k) ) );
    }
}

这是递归版本,使用C(n,k)= C(n-1,k)+ C(n-1,k-1)公式计算。

int binomial_coefficient_recursive(unsigned int n, unsigned int k){
    if (k == 0 || k == n) {
        return 1;
    }
    else {
        return binomial_coefficient_recursive(n - 1, k) + binomial_coefficient_recursive(n - 1, k - 1);
    }
}

最后但并非最不重要的是,你能用C(n,k-1)计算二项式系数C(n,k)吗?

1 个答案:

答案 0 :(得分:1)

解决方案都取决于递归。在第一个版本中,您可以使用简单迭代替换factorial的递归调用。

但是,在第二个解决方案中存在重新计算重叠子问题的问题。

  C(n, k) = C(n-1, k) + C(n-1, k-1) 

你应该使用memoization来缓存C(n,k)的值,只要它被计算存储值,当函数调用相同的参数时,重新计算,查找并返回值。

在第一个问题中,您正在多次调用阶乘函数,这是可以避免的。策略是计算增量变化。例如,当您计算factorial(k)时,您可以派生

    factorial(n) = factorial(k) * K+1 * K+2 ...n

这减少了你正在进行的乘法次数。

回到问题的时空复杂性。

第一:时间复杂度是O(n),这里是3个阶乘调用,你正在做n,k和n-k乘法

第二:它将是

    T(n,k) = T(n-1,k) + T(n-1,k-1) + O(1)           
    where T(n,n) = T(n,0) = O(1)

求解这个差分方程,你会得到T(n)= O(2 ^ n),(用于寻找斐波那契数列复杂度的相同参数)

所以后面的方法是指数的,可以使用memoization来降低。