简体   繁体   English

递归Pascal三角算法的多个时间复杂度解决方案?

[英]Multiple time complexity solutions for recursive Pascal triangle algorithm?

I have created the following simple algorithm in Java that computes the Pascal triangle in a recursive way, in the form of a 2D list of ints: 我在Java中创建了以下简单算法,该算法以2D整数列表的形式递归地计算Pascal三角形:

public class PascalTriangleRec{
    private final int[][] points;

    public PascalTriangleRec(int size){
        points = new int[size][];
        for (int i =0;i<size;i++){
            int[] row  = new int[i+1];
            for (int j = 0;j<=i;j++){
                row[j]=getValueAtPoint(i,j);
            }
            points[i]=row;
        } 
    }
    public static int getValueAtPoint(int row, int col){
        if (col == 0 || col == row) return 1;
        else return getValueAtPoint(row-1,col-1) + getValueAtPoint(row-1,col);
    }
}

I need to know the time complexity of this algorithm. 我需要知道此算法的时间复杂度。 I found another question on StackOverflow that gives the time complexity of the getValueAtPoint function as O(2^n/sqrt(n)). 我在StackOverflow上发现了另一个问题 ,该问题给出了getValueAtPoint函数的时间复杂度为O(2 ^ n / sqrt(n))。 I figured that since this function is embedded in two nested for loops, the time complexity of the entire Pascal triangle is O(sqrt(n^3)*2^n). 我发现由于此函数嵌入在两个嵌套的for循环中,因此整个Pascal三角形的时间复杂度为O(sqrt(n ^ 3)* 2 ^ n)。 I am pretty sure this reasoning is correct. 我很确定这个推理是正确的。

On the other hand I devised a completely different way to think about this problem, which goes as follows: 另一方面,我设计了一种完全不同的方式来考虑此问题,方法如下:

There is a certain property of Pascal triangles called Pascal's Corollary 8. This property states that the sum of all the coëfficients on a given row r is equal to 2^r, with r starting at 0. 有一个Pascal三角形的特定属性,称为Pascal推论8。此属性表明,给定行r上所有系数的总和等于2 ^ r,其中r从0开始。

One can also note that the getValueAtPoint function from my code sample will keep recursively calling itself until it returns 1 at some point. 还可以注意到,我的代码示例中的getValueAtPoint函数将继续递归调用自身,直到在某个点返回1为止。 This means that all the coëfficients in the Pascal triangle are formed by adding 1 as many times as the value of that coëfficient. 这意味着Pascal三角形中的所有系数都是该系数的值的1乘以1。

Since adding 1s takes a constant time, one can say that the time needed to compute a given row in the triangle is equal to some constant time multiplied by the combined value of all the coëfficients in that row. 由于加1需要固定的时间,因此可以说计算三角形中给定行所需的时间等于某个恒定时间乘以该行中所有系数的总和。 This means that the time complexity of a given row r in the triangle must be 2^r. 这意味着三角形中给定行r的时间复杂度必须为2 ^ r。

The time needed to compute the entire triangle is equal to the sum of the time needed to calculate all the rows in the triangle. 计算整个三角形所需的时间等于计算三角形中所有行所需的时间总和。 This results in a geometric series, which computes the sum of all 2^r for r going from 0 to n-1. 这产生了一个几何级数,该级数计算出r的所有2 ^ r的和从0到n-1。

Using the summation property of the geometric series, this series can be rewritten in the following form . 使用几何级数的求和属性,可以按以下形式重写该级数。

This means that the time complexity of the algorithm according to this last derivation is O(2^n). 这意味着根据该最后推导的算法的时间复杂度为O(2 ^ n)。

These two approaches yield different results, even though they both seem logical and correct to me. 尽管这两种方法在我看来都是合乎逻辑且正确的,但它们会产生不同的结果。 My question is in the first place if both these approaches are correct, and if both can be seen as correct at the same time? 我的问题首先是这两种方法是否正确,以及同时可以认为这两种方法都正确吗? As I view it both of them are correct, but the second one is more accurate since for the first one the worst-case scenario is taken for the getValueAtPoint function, and applied to all coëfficients, which is clearly not the case in reality. 在我看来,这两种方法都是正确的,但是第二种方法更准确,因为对于第一种方法, getValueAtPoint函数采用的是最坏的情况,并应用于所有系数,而实际上并非如此。 Does this mean that the first one becomes incorrect, even though the logic behind it is correct, just because a better approach exists? 这是否意味着即使第一个方法背后的逻辑是正确的,也只是因为存在更好的方法,第一个方法才变得不正确?

The simple answer is "too many variables". 简单的答案是“变量太多”。 First of all, your analysis is exactly correct: the complexity depends on the sum of all the values computed. 首先,您的分析是完全正确的:复杂度取决于所计算的所有值的总和。 The same logic underlies the answer that got you O(2^n/sqrt(n)). 答案也是O(2 ^ n / sqrt(n))的基础。

There are two problems: 有两个问题:

  • Little problem : Stirling's approximation is just that: some terms are elided. 小问题 :斯特林的近似值就是:某些术语被忽略了。 I think they fall out when you combine all the loops, but I'd have to work through the nasty details to be sure. 认为当您组合所有循环时它们会掉线,但是我必须仔细研究一些令人讨厌的细节才能确定。
  • Big problem : the values of n you combine are not the same n . 大问题 :N的你结合的值是不相同的N。 That last n value you incorporated is i running from 0 to size; 您合并的最后n个值是从0到size; each value of i becomes n for an initial call to getValueAtPoint . 对于getValueAtPoint的初始调用, i的每个值都将变为n

Try doing the sum from 0 to n on your previous complexity, and see what you get? 尝试对先前的复杂度进行从0到n的总和,看看会得到什么?

.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM