非平凡递归函数的时间复杂度

时间:2015-11-04 03:17:30

标签: java recursion time-complexity

我编写了一个递归函数,它接受一个正整数数组(> 0)(denominations)和一个整数值(amount),并返回获取数据的方式数。仅使用数组中的整数的值。因此,例如,整数数组可以被视为变化,整数值被视为您必须支付的金额。该功能返回您可以支付收银员的方式。例如:

amount = 4且denominations = [1,2,3,4]

这应该返回5

我测试了我的功能,它运行正常。调用函数时,参数accindex将作为0传递。这是函数:

public int count_number_of_ways(int amount, int acc, int index,  int[] denominations) {

        if (acc > amount) return 0;

        if (amount == acc) return 1;


        int len = denominations.length;
        int count = 0;

        while (acc < amount) {


            for (int i = index + 1; i < len; i++) {


                count += count_number_of_ways(amount, acc + denominations[i], i, denominations);


            }

            acc += denominations[index];

            if (acc > amount) return count + 0;

            if (acc == amount) return count + 1;

        }

        return count + 0;


}

我试图计算这个功能的时间复杂度,但碰到了一堵砖墙。递归调用是在for循环中的for循环内部,这让我感到困惑。任何人都可以帮我确定这个功能的时间复杂度吗?

1 个答案:

答案 0 :(得分:2)

一般来说,在最坏的情况下,您将花费时间与(amount / denominations[0])*(amount / denominations[1])* ... *({{1 }} / amount),其中n - 面额数。

这是因为您查看了每种面额的所有计数集。特定面额编号denominations[n]的最大计数为i / amount

在实际情况中,您会提前停止该过程,但我认为它不会改变O((amount / geometric_average_denomination)^ n)。

虽然可以避免指数时间。为此,您可以使用动态编程方法。这是我的算法版本需要O(金额* n)时间:

denominations[i]

想法是填充size [n] [amount]的矩阵,其中每个元素(i,j)是使用具有索引&gt; = i的面额子集的amount = j的解的数量。您只需填写此public static int count_number_of_ways(int amount, int index, Integer[][] cache, int[] denominations) { if (cache == null) cache = new Integer[denominations.length][amount + 1]; if (amount == 0) { int ret = 1; cache[index][amount] = ret; return ret; } if (cache[index][amount] != null) { return cache[index][amount]; } int ret = 0; if (index + 1 < denominations.length) ret += count_number_of_ways(amount, index + 1, cache, denominations); if (amount >= denominations[index]) ret += count_number_of_ways(amount - denominations[index], index, cache, denominations); cache[index][amount] = ret; return ret; } 矩阵的每个元素一次,如果已经定义,则稍后重复使用。

使用它像:

cache