递归G(n)函数错误

时间:2015-03-11 04:01:50

标签: java algorithm recursion

我有一个函数来计算g(n),其中g(n)= f(n,n)并且可以递归地定义为

f(i,j)= 1 3 (f(i - 1,j)+ f(i - 1,j - 1)+ f(i,j - 1)),

f(0,0)= 0; f(i,0)= 1,i> 0; f(0,j)= 1,j> 0

static final Map<List<Double>, Double> CACHE = new HashMap<>();

private static double f(double i, double j) {
    if (i == 0.0 && j == 0.0) return 0.0;
    if (i == 0.0 || j == 0.0) return 1.0;
    List<Double> key = Arrays.asList(i, j);
    Double a = CACHE.get(key);
    if (a != null)
        return a;
    double result =  (1.0 / 3) * (f(i - 1, j) + f(i - 1, j - 1) + f(i, j - 1));

    CACHE.put(key, result);
    return result;
}

private static double g(double n) {

    return f(n, n);

}



}

我试图计算n = 10 ^ 1,10 ^ 2,10 ^ 3,10 ^ 4,10 ^ 5,10 ^ 6的值。前3个结果计算得很好,但接下来程序崩溃了:

Exception in thread "main" java.lang.StackOverflowError
at java.util.HashMap$TreeNode.getTreeNode(HashMap.java:1873)
at java.util.HashMap.getNode(HashMap.java:575)
at java.util.HashMap.get(HashMap.java:556)
at javaapplication7.Question3.f(Question3.java:72)

有人能看到解决这个问题的方法吗?那么存储和运行时间的复杂性又是什么呢?

1 个答案:

答案 0 :(得分:1)

问题就像异常的名称一样:StackOverflowError。对于n = 10000的情况,我们需要调用函数f 10000 * 10000次,并且所有函数调用都保存在堆栈内存中,这会导致堆栈溢出。

  • 因此,一个选项是可以增加Java堆栈大小。

  • 或者,您可以考虑从递归方法转变为迭代方法。

观察:要计算状态f(i, j),我们只需要知道状态f(i - 1, j), f(i - 1, j - 1)和状态f(i, j - 1),它只需要两个数组,一个保存当前{{1 },一个包含i的结果。所以我们可以提出这样的迭代解决方案,只需要O(2 * n)空间:

i - 1