计算 space 字符串压缩的复杂度 - 破解编码面试

Calculating space complexity of string compression - Cracking the coding interview

我试图理解 space 以下代码的复杂性。该代码将字符串从 "aabbbb" 压缩到 "a2b4"。问题是 Cracking the coding interview version 5 (2013) 第 1 章的问题 5,代码取自 solutions

 public static String compressBetter(String str) {
    int size = countCompression(str);
    if (size >= str.length()) {
        return str;
    }
    StringBuffer mystr = new StringBuffer();
    char last = str.charAt(0);
    int count = 1;
    for (int i = 1; i < str.length(); i++) {
        if (str.charAt(i) == last) {
            count++;
        } else {
            mystr.append(last);
            mystr.append(count);
            last = str.charAt(i);
            count = 1;
        }
    }
    mystr.append(last);
    mystr.append(count);
    return mystr.toString();
}   

哪里

public static int countCompression(String str) {
    if (str == null || str.isEmpty()) return 0;
    char last = str.charAt(0);
    int size = 0;
    int count = 1;
    for (int i = 1; i < str.length(); i++) {
        if (str.charAt(i) == last) {
            count++;
        } else {
            last = str.charAt(i);
            size += 1 + String.valueOf(count).length();
            count = 1;
        } 
    }
    size += 1 + String.valueOf(count).length();
    return size;
}

根据作者 compressBetter 的复杂度为 O(N) space。 为什么不是 O(1)? 在 countCompression 的每个 运行 中,我们持有 lastsizecount 以及类似的 compressBetter(持有 countCompression 变量加上mystr, last, count。我对space复杂度的理解是"how much memory the algorithm needs/holds at any time"。换句话说,space复杂度不像时间复杂度那样是不累积的。

请注意,作者在书中只考虑了人们称为 "auxiliary space complexity" 的内容(没有存储输入所需的 space),如上例所示。另外,afaik 在这本书的 errata 中没有条目。

更新:我的困惑来自以下示例(同一本书中的问题 1.1)

public static boolean isUniqueChars2(String str) {
  boolean[] char_set = new boolean[256];
  for (int i = 0; i < str.length(); i++) {
    int val = str.charAt(i);
    if (char_set[val]) return false;
    char_set[val] = true;
  }
  return true;
}    

尽管有 256 个布尔数组分配,但它还是 O(1) - 我认为分配在计算 space 复杂度时无关紧要。但实际上它是 O(1),因为所需的 space 是常数并且与输入大小无关(与 mystr Stringbuffer 不同)。

您问的是 compressBetter 的 space 复杂度,其中包括对 countCompression 的调用,但还执行额外的工作。

虽然 countCompression 的 space 复杂度确实是 O(1),但 compressBetter 具有线性 space 复杂度(即 O(N))最坏的情况(输入 String 中没有两个连续字符相等),因为在这种情况下它会产生 2N 个字符的 StringBuffer

只需将我之前的评论转换为答案:您持有一个 StringBuffer,其大小可能与字符串的大小成正比。想想你有一个没有连续重复字符的输入字符串的情况(最糟糕的情况)。