n位二进制排列表示的时间复杂度

时间:2019-01-06 03:38:10

标签: java algorithm time time-complexity

我已经在Java中返回了以下代码,以生成可能的n位二进制表示形式。

public List<String> binaryRepresenation(int n){
    List<String> list = new ArrayList<>();
    if(n>0){
        permuation(n, list, "");
    }
    return list;
}

private void permuation(int n, List<String> list, String str){
    if(n==0){
        list.add(str);
    }else{
        permuation(n-1, list, str+"0");
        permuation(n-1, list, str+"1");
    }
}

对于n = 3,它产生001 001 010 011 100 101 110 111组合。 总体而言,此功能会产生2 ^ n种可能的表示形式。

可以肯定地说时间复杂度是n * 2 ^ n

在2 ^ n次的情况下,针对基本情况调用该方法。为了达到每种基本情况,将调用置换方法最多n次。

那么总的上限时间复杂度是n * 2 ^ n吗?如果我错了,请纠正我。我基于此线程Time Complexity of Permutations of a String中讨论的字符串排列时间复杂度得出了这个结论。您的帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

您的分析存在一个小问题。如您所见,对于每种基本情况,您必须调用该函数n次。但是,其中一些调用被其他基本情况共享。换句话说,您多次计算同一呼叫。

这意味着尽管复杂度绝对不能大于n * 2 ^ n,但实际上可能更低。

要计算复杂度的更好界限,可以计算对permutation函数的实际调用次数。一种实现方法是考虑str变量的可能值。

str将是长度小于或等于n的二进制字符串。另外,每次对permutation函数的调用都会收到一个唯一的值str。这意味着该函数被调用的次数等于长度为<= n的二进制字符串的数量。

有多少个这样的字符串? 1 + 2 + 4 + ... + 2 ^ n = 2 ^ (n + 1) - 1

因此,permutation的调用次数为O(2^n)。 但是每个调用都包含操作str + "0"str + "1"。这些操作需要O(n)时间。因此,该操作的净时间复杂度为:O(n * 2^n),但出于与您最初想象的原因不同的原因。

答案 1 :(得分:1)

时间复杂度为O(2 n )。每个函数调用将两个新的函数调用压入堆栈,直到达到基本情况为止。可视化p $3.gsub(/20/,"").gsub(/../) { |b| b.hex.chr } 的树,如下所示:

n = 3

这是一个完美的二叉树,具有15个节点和8个叶子。访问了2 n + 1 个状态,但是我们可以删除常数并将其简化为O(2 n )。

字符串串联使复杂度增加了 ________""________ / \ ___0___ ___1___ / \ / \ _00_ _01_ _10_ _11_ / \ / \ / \ / \ 000 001 010 011 100 101 110 111 ,但是将n或容器与恒定时间的push / pop或add / remove操作一起使用可以消除这种情况,这表明这只是一个实现特定于您发布的代码的细节,而不是一般算法的复杂性。