了解这个时间复杂性问题(破解编码面试)

时间:2018-06-19 22:29:11

标签: algorithm time-complexity big-o stringbuilder

问题:

String joinWords(String[] words) {
    String sentence = "";

    for (String w : words) {
        sentence = sentence + w;
    }

    return sentence;
}

所以解决方案是 O(xn ^ 2)

据我了解,对于每次迭代,变量“句子”中的字母数量增加一。我认为哪个是O(n ^ 2)?

“ x”是否只是“单词”数组中字母的数量?

答案:在每个串联中,将创建字符串的新副本,并将两个字符串逐个字符地复制过来。第一次迭代需要我们复制x个字符。第二次迭代需要复制2个字符。第三次迭代需要3倍,依此类推。因此,总时间为O(x + 2x + ... x nx)。这减少到O(xn ^ 2)

1 个答案:

答案 0 :(得分:-2)

答案有两种错误。 O(xn ^ 2)不存在。在大O中,您删除所有常数。如果正确(不是),则为O(n ^ 2)。

下一部分取决于语言,字符串的+实现和字符串类本身。如果字符串类是可变的,则假定它具有适当的实现,则+应该为O(n)(不会在每次使用+时引起重新分配和复制)。如果字符串类是不可变的,则取决于字符串的实现方式-它对所有数据使用单个字符缓冲区,还是可以处理有序列表中的多个字符指针?当然,即使是最差的实现,也不会是O(n ^ 2),更像是O(n)(每次迭代2个副本)的O(2n)。任何给我答案O(n ^ 2)的人都会被标记为错误。但是实际上任何现代String类实现都是没有常量的O(n),并且在空间上几乎是O(n * l)(其中n是单词数,l是平均单词长度)。

class String {
  String base;   //used for appended strings
  String additional;  //used for appended strings
  char baseData[];  //used for pure strings

  String(String base, String additional) {
     this.base = base;
     this.additional = additional;
  }

  operator + (String newString) {
      return new String(this, newString);
  }

   //As an example of how this works
   int length() {
      if(base != null) {
        return base.length()+additional.length(); //This can be cached, and should be for efficiency.
      }
      else {
         return baseData.length;
      }
   }
}

请注意,+为O(1)。是的,我知道Java没有运算符重载,该函数在那里显示了其实现方式。