繁体   English   中英

字符串排列算法的复杂性

[英]Complexity of a string permutation algorithm

考虑以下代码来置换包含McDowell的唯一字符的字符串:

该代码基于递归,并通过在每个位置放置一个字符将其添加到每个结果中。 如果字符串包含n个字符,则存在n + 1个这样的位置。

由于对于每个字符串(可能有n个长度为n的字符串),您要添加n + 1个字符,因此复杂度应为1! + 2! + ... +(n + 1)!

作者说复杂度为O(n!)。 这和O(1!+ ... +(n + 1)!)一样吗? 如果是这样,为什么?

public static ArrayList<String> getPerms(String str){
    if (str == null){
      return null;
    }

    ArrayList<String> permutations = new ArrayList<String>();
    if (str.length() == 0){
      permutations.add("");
      return permutations;
    }

    char first = str.charAt(0);
    String remainder = str.substring(1);
    ArrayList<String> words = getPerms(remainder);
    for (String word: words){
      for (int j = 0; j <= word.length(); j++){
        String s = insertCharAt(word, first, j);
        permutations.add(s);
      }
    }
    return permutations;
  }

  public static String insertCharAt(String s, char c, int j){
    String start = s.substring(0, j);
    String end = s.substring(j+1);
    return start + c + end;
  }

让我们将F(n)定义为getPerms返回的列表的长度,当您将长度为n的字符串传递给它时。

通过检查基本情况,我们看到F(0) == 1

在递归的情况下,如果字符串的长度为n > 0 ,则getPerms长度为n-1的字符串进行递归调用。 它获取长度为F(n-1)的列表(即F的定义),并将该列表存储在words 对于words每个元素,它将n元素添加到permutations 因此, permutations在返回时将具有n * F(n-1)元素。

因此, F(n) == n * (n-1) * (n-2) * ... * 1 == n! getPerms函数返回长度为n!的列表n! 给定一个长度为n的字符串。

现在, getPerms复杂性getPerms 我假设我们正在谈论时间复杂性。 好吧,它执行∑ i = 0 n i! list总共追加(最外层调用n !,第一个递归调用加(n-1)!,第二个递归调用加(n-2)!,等等)。 因此,您可以说复杂度是O(∑ n i!)列表的追加。

但是列表追加并不是这里唯一的计算方法。 当我们在Java中加入字符串时,我们会在周围复制很多字符。

假设G(n)是在传递长度为n的字符串时对getPerms的调用执行的字符副本n

通过检查基本情况,我们看到G(0) == 0

在递归的情况下, getPerms在长度为n-1的字符串上调用自身,该字符串执行G(n-1)字符副本并返回F(n-1)字符串的列表,每个字符串的长度为n-1 然后getPerms每个字符串复制n次,然后在每个副本中插入另一个字符,因此F(n-1) * n * n == n * n! 除了递归中的G(n-1)外,还直接在getPerms调用中直接复制的字符。

因此,通过调用getPerms复制的字符数为O(∑ i = 0 n i * i!)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM