具有两个输入的递归函数的运行时间

时间:2014-03-23 20:30:17

标签: algorithm recursion complexity-theory

我一直在解决一些面试问题,我正在努力确定某些递归函数的运行时间。 我正在解决的问题是:

  

想象一下,机器人坐在X by Y网格的左上角。   机器人只能向两个方向移动:向右和向下。多少   机器人从(0,0)到(X,Y)的可能路径是什么?

我的解决方案(用Java编写):

public int totalPossiblePaths(int X, int Y) {
    if(X < 0 || Y < 0) {
        return 0;
    }
    if(X == 0 && Y ==0) {
        return 1;
    }
    return totalPossiblePaths(X - 1, Y) +
           totalPossiblePaths(X, Y - 1);
}

此外,我对这个节目的空间和时间复杂性进行了分析,就大事而言,因为采访需要我知道。 我得出结论,空间复杂性是:

  

O(X + Y)

由于最多会有X个递归调用,后跟Y递归调用,因此最多X + Y函数调用将被推送到堆栈上。

但是,运行时间的复杂性对我来说并不是很清楚。 我绘制了递归树,很明显递归(至少)是指数的。 我似乎无法确定X和Y之间的关系。

示例递归(没有X&lt; 0或Y&lt; 0的调用以提高可读性):

    F(3, 2) = F(2, 2) + F(3, 1)
            = F(1, 2) + F(2, 1) + F(2, 1) + F(3, 0)
            = F(0, 2) + F(1, 1) + F(1, 1) + F(2, 0) + F(1, 1) + F(2, 0) + F(2, 0)
            = F(0, 1) + F(0, 1) + F(1, 0) + F(0, 1) + F(1, 0) + F(1, 0) + F(0, 1) + F(1, 0) + F(1, 0) + F(1, 0)
            = F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0) + F(0, 0)

最后一级有10个元素(返回值1),它是从(0,0)到达(3,2)的可能路径数。 根据我的直觉,我认为运行时间会相对于X和Y增长:

  

O(2 ^ X * 2 ^ Y)= O(2 ^(X + Y))

此外,我添加了一个计数器,该计数器随每次递归调用递增,以查看调用该函数的次数。对于上面的示例,函数被调用49次。 该函数成功传递了两个if语句24次,并尝试再进行2次递归调用。

这让我更加怀疑自己的直觉。

有人可以帮我分析这个(和类似的)递归函数来确定时间复杂度吗? 我不是在寻找你们这些人如何解决这个问题的深度解释,但也许是一些一般的指示或建议?感谢。

3 个答案:

答案 0 :(得分:0)

当每个summand为S0时,总和1需要多少个加数?嗯,显然至少S。因此,您的函数至少会进行answer次调用,其中answer是问题的答案。如果你只返回那些,那将是确切的计数,否则处理零。

为了记录,问题的一个很好的解决方案与Pascal's Triangle有很大关系(这个picture可能有帮助)。

答案 1 :(得分:0)

有一个更简单的解决方案:要从(0,0)到(x,y),它必须总共采取x + y步。在那些你必须选择x水平步骤的位置,你可以用二项式(x + y,x)方式。

答案 2 :(得分:0)

整蛊,每个问题都不一样。从一个电子表格开始,该电子表格计算调用问题的调用次数。

如果您从X = Y&gt;开始0,做递归调用X + Y级别深度,然后有2 ^(X + Y)种方式可以选择两个递归调用。许多方法不会深入X + Y水平,因为X或Y变为负数。但是如果你按照每个呼叫路径进行相同的次数,那么你将深入到X + Y级别。有(超过X的2倍)方法,大约是2 ^(X + Y)/ sqrt(pi X)。