【问题标题】:Time complexity of string build algorithm字符串构建算法的时间复杂度
【发布时间】:2017-04-28 11:56:35
【问题描述】:
String joinWords (String[] words){
   String sentence = "";
   for(String w: words){
     sentence = sentence + w;
   }
  return sentence;
}

这本书报道这是O(xn^2)

这是我的工作:

1 次调用最初创建 String sentence

有 N 次调用(由于 for 循环的 N 次调用)

那么有N次调用分配sentence = sentence + w

最后一次发送return sentence;

总计:

这给出 O(N^2 + 2) = O(N^2)

问题 (1) 我的工作是否正确?

(2) 他们从哪里得到O(xn^2) 中的x 的额外因子?

谢谢!

【问题讨论】:

  • 只有 O(n)!
  • "那么有 N 个调用来赋值 sentence = sentence + w" true,但是为什么这些 N 需要与另一个 N 相乘呢?
  • 什么抽象机器模型/运行时环境/编程语言? sentence = sentence + w; 是否一直在努力?
  • x 是单词的平均长度,但时间复杂度是 O((xn)^2)。可以通过 StringBuilder 优化为 O(xn):stackoverflow.com/q/7156122/6809386

标签: algorithm


【解决方案1】:

这是一个写得很糟糕的例子,因为它会重新分配句子N 次而不是一次导致O(x.N^2)

String sentence = "";
for(String w: words) // this loops N times (if N is number of words)
 sentence = sentence + w; // this reallocates the whole thing

如果sentence = sentence + w;O(1),则结果将为O(N),但事实并非如此,因为:

 sentence = sentence + w;

实际上是这样的:

String temp = new string of size (sentence.size + w.size);
for (i=0;i<sentence.size;i++) temp[i]=sentence[i];
for (i=0;i<w.size;i++) temp[i+sentence.size]=w[i];
sentence=temp; // just pointer assignment O(1)
delete temp;

这是O(M),其中M是结果句子中的字母数,平均为x.Nx是每个单词的平均字母数)。

所以最终的复杂性是O(x.N^2)(不考虑摊销),而如果使用预分配步骤,它可能只是O(x.N) ...

【讨论】:

    【解决方案2】:

    总计:

    这给出 O(N^2 + 2) = O(N^2)

    把你的周期像这样:

    String joinWords (String[] words){
       String sentence = "";
       // words.length is a constant, no calls are made
       for(int i=0; i<words.length; i++){
         sentence = sentence + w;
       }
      return sentence;
    }
    

    虽然sentence = sentence + w; 确实是“数据操作”,但您在所谓的 O(N^2) 中的另一个 N 来自哪里?

    【讨论】:

      猜你喜欢
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 2016-05-24
      • 2015-05-20
      • 2013-08-10
      相关资源
      最近更新 更多