java - 递归 G(n) 函数错误

标签 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)

谁能找到解决这个问题的方法?另外,存储和运行时的复杂性是多少?

最佳答案

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

  • 因此,一种选择是您可以增加 Java 堆栈大小。

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

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

int[] lastResult = new int[n + 1];

for(int i = 1; i < n; i++){
    int[] f = new int[n + 1];
    for(int j = 1; j <= n; j++){
        f[j] = lastResult[j] + lastResult[j - 1] + f[j - 1];
    }
    lastResult = f;
}

关于java - 递归 G(n) 函数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28978338/

相关文章:

bash - 递归计算特定文件BASH

python - 递归和二叉树

java - sql查询在eclipse中不起作用

java - 同一 .java 文件中任何其他顶级类的可访问性如何?

java - 在二叉搜索树中寻找中序后继

algorithm - 二叉堆索引

java - 如何使用 jQuery 将包含对象数组的对象数组传递给 Spring MVC Controller ?

java - 用户界面未对齐

algorithm - 将学生分成两组的图算法

使用模板函数的 C++ 模板元编程