循环时间复杂度内的递归

时间:2018-12-22 17:27:56

标签: algorithm time-complexity complexity-theory

我创建了此算法来使用回溯策略解决问题。问题在于:

  

给出由n个整数和两个整数值m和c组成的集合A。计算m个元素的A的所有子集,它们的值之和为c。

算法(在Java中)

public class Algorithm {

    private List<Integer> a;
    private int m;
    private int c;

    /**
     * @param a Initial set
     * @param m Maximum number of elements stored in the subset
     * @param c Desired sum
     */
    Algorithm(List<Integer> a, int m, int c) {
        this.m = m;
        this.c = c;
        this.a = a;

        findSubsets(0, new int[m], 0, 0);
    }

    /**
     * @param i Index to go through the initial set
     * @param subset Solution candidate
     * @param level Current number of elements stored in the subset
     * @param sum  Current sum of the elements stored in the subset
     */
    private void findSubsets(int i, int[] subset, int level, int sum) {

        // Base case
        if (level == m) {
            if (sum == c) {
                System.out.println(Arrays.toString(subset));
            }
        }

        // Exploration
        else {
            while (i < a.size()) {
                subset[level] = a.get(i);

                findSubsets(i + 1, subset, level + 1, sum + a.get(i));

                i++;
            }
        }
    }
}

时间复杂度:

通过这种解决方案,我实验确定了当m趋于n时,复杂度趋于O(2 ^ n)。但是,在通读了有关如何计算时间复杂度的指南之后,我仍然无法从数学上确定该结果。我对平均情况也非常感兴趣,而我对如何计算它非常迷茫。

我知道这可能是一个新手问题,但是如果有人可以帮助我,我将不胜感激!谢谢

2 个答案:

答案 0 :(得分:0)

当您考虑O(m * 2^m)的所有子集时,算法的时间复杂度将为A,因为您认为m的所有子集小于或等于level他们!。与m的乘积用于求和每个子集的值。

答案 1 :(得分:0)

该算法计算每个子集,假设m = n。对于每个0<=i<n,您将i-1处的子集数量加倍,因为级别i-1的每个子集有两种情况可以将它们带到i级:添加a[i],否则不添加。

例如,如果i = 2并且有4个可能的子集(例如{},{A},{B},{AB}),那么对于i = 3,将有4个不包含{ {1}}(与之前相同),以及4个确实包含a[3]的新子集(例如{C},{AC},{BC},{ABC}),总共8个。

由于我们为每个a[3]加倍,因此在n = m的情况下,可能的子集总数为i<n