【问题标题】:Time complexity of these 2 program这两个程序的时间复杂度
【发布时间】:2017-12-11 14:57:42
【问题描述】:

我是复杂性分析的新手。任务是给定一个像“Code”这样的非空字符串,返回一个像“CCoCodCode”这样的字符串。我有这两个程序在做同样的事情。

方案一:

public String stringSplosion(String str) {
    String result = "";
    for (int i=0; i<str.length(); i++) {
        for(int j=0;j<=i;j++)
            result += str.charAt(j);
    }
    return result;
}

所以,上面的一个非常简单,这个程序有 O(n^2) 复杂度。

方案二:

public String stringSplosion(String str) {
    String result = "";
    // On each iteration, add the substring of the chars 0..i
    for (int i=0; i<str.length(); i++) {
        result = result + str.substring(0, i+1);
    }
    return result;
}

从另一个 StackOverflow 问题来看,str.substring() 的时间复杂度似乎为 O(n)。在这种情况下,程序 2 也具有 O(n^2) 时间复杂度。

我的分析是正确的还是我遗漏了什么?

【问题讨论】:

  • 是的,你是对的。
  • 甚至更多,您可以通过使用 StringBuilder 而不是字符串连接来使其更快一些(但仍然是 O(n^2))。顺便提一句。所有解决这个问题的算法都至少有 O(n^2) 的时间复杂度,因为输出的长度是 O(n^2)。
  • 我认为你是对的。您始终可以使用非常长的字符串测试执行时间。例如,如果从 length=1000 变为 length=2000,这两种方法的执行时间是否会增加 4 倍?

标签: java string algorithm time-complexity


【解决方案1】:

事实上,两者具有相同的复杂性 - O(n^3)。那是因为您使用+= 来连接答案!那里有一个您没有考虑到的隐藏循环,以及Schlemiel the Painter's Algorithm 的经典示例。您应该改用StringBuilder,这是构建字符串的正确方法。

【讨论】:

  • @Stefan 确实!有显式循环,substring 操作中的循环,最后是+ 连接操作中的循环
  • 虽然这是一个很好的观察,但编译器会在内部将他的字符串连接转换为 StringBuilder。 docs.oracle.com/javase/specs/jls/se8/html/…
  • 是的,但不一定有用。这取决于它的声明位置 - 在循环内部或外部
【解决方案2】:

请原谅缩进,但这本质上是满足测试的解决方案。

    public String stringSplosion(String str) {
      // Empty String test
      if (str.length() == 0) 
        return str;

      StringBuilder sb = new StringBuilder();

      for (int i=0; i<=str.length() ; i++) {
        sb.append(str.substring(0,i));
      }
      return sb.toString();
   }

【讨论】:

    猜你喜欢
    • 2021-06-14
    • 1970-01-01
    • 2021-02-25
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    相关资源
    最近更新 更多