algorithm - 如何使用内存计算递归的时间复杂度?

标签 algorithm recursion big-o complexity-theory memoization

下面代码的时间复杂度是多少?我知道它有多次递归调用,所以它可能应该是 3^n,但每次它都初始化长度为 n 的数组,这是后来使用的,这让我有点困惑。如果我们添加额外的数组来应用内存,时间复杂度应该是多少?下面是 Hackerrank Java 1D Array (Hard) 任务的解决方案。

public static boolean solve(int n, int m, int[] arr, boolean[] visited, int           curr) {
    if (curr + m >= n || curr + 1 == n) {
        return true;
    }

    boolean[] newVisited = new boolean[n];
    for (int i = 0; i < n; i++) {
        newVisited[i] = visited[i];
    }

    boolean s = false;
    if (!visited[curr+1] && arr[curr+1] == 0) {
        newVisited[curr+1] = true;
        s = solve(n,m,arr,newVisited,curr+1);
    }
    if (s) {
        return true;
    }
    if (m > 1 && arr[curr+m] == 0 && !visited[curr+m]) {
        newVisited[curr+m] = true;
        s = solve(n,m,arr,newVisited,curr+m);
    }
    if (s) {
        return true;
    }
    if (curr > 0 && arr[curr-1] == 0 && !visited[curr-1]) {
        newVisited[curr-1] = true;
        s = solve(n,m,arr,newVisited,curr-1); 
    }
    return s;
}

最佳答案

您的实现似乎确实具有指数级的复杂性。我并没有真正考虑过你问题的这一部分。提出最坏的情况可能有点乏味。但是一个“至少相当糟糕”的场景是将 arr 中的第一个 n-m 元素设置为 0,将最后一个 m元素设置为 1。那里有很多分支,并没有真正利用内存机制。我猜你的解决方案至少是 n/m 的指数。

这是另一种解决方案。我们可以将问题改写为图形问题。让数组中的元素成为有向图的顶点,并让以下形式之一的每对顶点之间有一条边:(x,x-1)(x,x+1)(x,x+m),如果这样一条边的两端的值为 0。添加一个额外的顶点 t 到你的图表。还从 {n-m+1,n-m+2,...,n} 中每个值为 0 的顶点添加一条边到 t。所以我们的图中只有 3n+m 条边。现在,你的问题等同于确定我们刚刚构造的图中是否存在从顶点 0t 的路径。这可以通过从顶点 0 开始运行深度优先搜索来实现,复杂度为 O(|E|),在我们的例子中为 O(n+ m).

回到您的解决方案,您正在做几乎相同的事情(可能没有意识到)。唯一真正的区别是您正在将 visited 数组复制到 newVisited 中,因此永远不会真正使用所有内存:p 所以,只需删除 newVisited , 在使用 newVisited 的任何地方使用 visited 并检查会发生什么。

关于algorithm - 如何使用内存计算递归的时间复杂度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33836644/

相关文章:

java - 如何在前端和后端实现问答逻辑

algorithm - Warshall算法思想及可能的改进

c# - 在递归中使用 Math.Pow() 时,超出了 C# 的执行时间限制

algorithm - 如果 m<n,O(n+m) 和 O(n) 符号是否等效?

algorithm - 这些输入的合并排序的运行时间是多少

f# - F# 函数的最坏情况渐近时间复杂度

algorithm - 两个平方和 : Where's My Error?

arrays - 给定一个数字列表和一个数字 k,返回列表中的任意两个数字是否相加为 k

Java-构建一个用零替换偶数的递归

ruby - 这个方法在ruby中如何使用自己的方法呢?