【问题标题】:The time complexity for a code segment代码段的时间复杂度
【发布时间】:2011-08-02 18:46:10
【问题描述】:

从网上的笔记中,我读到了下面的 java 代码 sn-p 用于反转一个字符串,据称它具有二次时间复杂度。在我看来,i 的“for”循环只是迭代了 s 的整个长度。它是如何导致二次时间复杂度的?

public static String reverse(String s)
{
  String rev = new String();
  for (int i = (s.length()-1); i>=0; i--) {
      rev = rev.append(s.charAt(i));
  }
  return rev.toString();
}

【问题讨论】:

  • 你也连接到字符串,这是相当昂贵的,因为它们是不可变的。 (你的代码有一些错误,它不会编译)
  • 这不会反向返回字符串,因为它总是会为其添加一个额外的空间。
  • 为什么有人写这个,而不是仅仅使用 String 的 reverse 方法是我无法理解的(除非他们想要额外的空间,这只是......奇怪)。
  • 令 n = s 的长度, f 为算法的时间复杂度函数。如果算法只是迭代 s 的整个长度,那么必须存在一些常数 a 和 b 使得 f(n)b.

标签: java string algorithm data-structures


【解决方案1】:
public static String reverse(String s)
{
  String rev = " ";
  for (int i=s.length()-1; i>=0; i--)
  rev.append(s.charAt(i); // <--------- This is O(n)
  Return rev.toString();
}

我复制粘贴了您的代码。我不确定你从哪里得到这个,但实际上 String 没有 append 方法。也许revStringBuilder 或另一个Appendable

【讨论】:

    【解决方案2】:

    可能是因为append 调用不会在恒定时间内执行。如果它与字符串的长度成线性关系,那就可以解释了。

    【讨论】:

      【解决方案3】:

      append 必须找到字符串的结尾,即Ο(n)。所以,你有一个 Ο(n) 循环执行了 Ο(n) 次。

      【讨论】:

        【解决方案4】:

        我不认为 String 有 append 方法。所以,这段代码不会编译。

        但是,谈到二次复杂度的问题,让我们假设您实际上是使用 '+' 运算符或 String.concat() 方法在字符串中附加一个字符。 String 对象是不可变的。因此,每当您附加到一个字符串时,都会创建一个更大长度的新字符串,将旧字符串内容复制到其中,然后附加最后一个字符,并销毁前一个字符串。因此,随着字符串的增长,这个过程需要越来越多的时间。

        附加循环需要 O(n) 时间,但对于每个循环,您需要 O(n) 时间来逐个字符地复制字符串。这会导致二次复杂度。

        最好使用 StringBuilder 或 StringBuffer。但是,我猜您提到的时间复杂度将与较旧的 java 编译器有关。但是,新的高级编译器实际上会使用 StringBuilder 优化“+”操作。

        【讨论】:

          猜你喜欢
          • 2013-11-18
          • 1970-01-01
          • 2020-07-24
          • 1970-01-01
          • 1970-01-01
          • 2021-06-23
          • 2021-10-23
          • 2018-08-29
          • 2018-03-19
          相关资源
          最近更新 更多