【问题标题】:Complexity of finding all substrings of a string查找字符串的所有子字符串的复杂性
【发布时间】:2013-07-04 20:29:23
【问题描述】:

这里是查找字符串的所有子字符串的解决方案。

for (int i = 0; i < str.length(); i++) {
    String subStr;
    for (int j = i; j < str.length(); j++) {
        subStr = str + str.charAt(j));
        System.out.println(subStr);
    }
}

我在整个互联网上读到这段代码的复杂度是 O(n2)。 但是 + 操作是 O(n) 操作。 因此,在我看来,复杂度应该是 O(n3)。

如果我错了,请纠正我的理解。

【问题讨论】:

  • 不要使用+。请改用StringBuilder

标签: java complexity-theory


【解决方案1】:

将字符添加到字符串是 O(1) 操作。如果您还考虑使用println 打印输出所需的时间,您将得到 O(n3)。

【讨论】:

  • "将字符添加到字符串是 O(1) 操作":这是不正确的,因为 String 是不可变的,连接发生在 O(n) 时间内。您可以使用 StringBuilder 代替,它有 O(1) 时间。
  • @VyshnavRameshThrissur 你确定吗?这取决于内部实现。 Tha java 编译器可能(并且应该)注意到旧值被丢弃,因此在适当的位置添加字符。
  • 是的。 stackoverflow.com/questions/15400508/… stackoverflow.com/questions/4323018/… 简而言之,在添加两个字符串的过程中,会创建一个新的 StringBuilder。第一个字符串字符被复制到这个,第二个字符串字符被附加到这个。然后使用 toString() 将其转换为字符串并返回。
【解决方案2】:

查找一个字符串的所有子字符串是 O(n2) (通过查找一个子字符串我的意思是确定它的开始和结束索引),很容易看出,因为子字符串的总数是 O( n2)。

但是将它们全部打印出来是 O(n3),因为要打印的字符总数是 O(n3)。在您的代码中,println 增加了 O(n) 复杂度(如果使用/实施得当,+ 运算符应该具有 O(1) 复杂度)。

【讨论】:

    【解决方案3】:

    从一个字符串中找到所有子字符串,这种简单的方法确实是 O(n^2)。但是问题中的代码可能不会那样做。这是修正后的版本。

        for (int i = 0; i < str.length(); ++i) {
            //Initialize with max length of the substring 
            StringBuilder prefix = new StringBuilder(str.length() - i);
            for (int j = i; j < str.length(); ++j) {
                prefix.append(str.charAt(j)); //this step is O(1).
                System.out.println(prefix); //this step is supposed to be O(1)
            }
        }
    
    The total number of iterations is given by
    Outer Loop  : Inner Loop
    First time  : n
    Second time : n - 1
    Third Time  : n - 2
    ..
    n - 2 time  : 2
    n - 1 time  : 1 
    
    
    
    So the total number of iterations is sum of iterations of outer loop plus sum of iterations of the inner loop.
    n + (1 + 2 + 3 + ... + n - 3 + n - 2 + n - 1 + n) is  = O(n^2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-01
      • 2012-10-24
      • 2012-04-20
      • 2019-03-11
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多