【问题标题】:Algorithmic complexity of string rotation字符串旋转的算法复杂度
【发布时间】:2021-03-04 08:32:46
【问题描述】:

我对复杂性有点陌生,并试图确定以下过程的算法复杂性,该过程计算给定字符串是否是另一个给定字符串的旋转(即,如果“bcdea”是“ abcde”)。我很确定这会分解为 O(n),因为函数中的每次检查在最坏的情况下都会分解为 n(我认为!)。听起来对吗?

public class Rotate {
        public static void main(String[] args) {
            String str1 = "abcde";
            String str2 = "bcdea";
            System.out.println(isRotation(str1, str2));
        }
        
        public static boolean isRotation(String str1, String str2) {
          if(str1 == null || str2 == null){
            return false;
          }
          
          System.out.println(str1 + str2);
          if(str1.length() == str2.length() && (str1 + str2).indexOf(str2) > 0){
            return true;
          }
          
          return false;
        }
    }

【问题讨论】:

  • 算法复杂度不衡量运行时间。
  • 呸,抱歉,我指的是算法复杂度,而不是运行时间。

标签: java time-complexity


【解决方案1】:

有争议的表达是这样的:

(str1 + str2).indexOf(str2)

您的方法中的其他所有内容显然都是O(1),因此无论这个表达式的复杂性是什么,都将是整个方法的复杂性。假设n1 代表str1 的长度,n2 代表str2 的长度。

现在,这里有两个部分。字符串连接通常可以假设为具有O(n1 + n2) == O(n) 运行时,因为组件操作是(1)分配空间(常量)、复制str1(需要n1 时间)和复制str2(需要n2 时间) )。

同时,Java's String.indexOf() has complexity O(m * n),其中m 是搜索字符串的长度,n 是模式字符串的长度。在这里,解析为O((n1 + n2) * n) == O(n * n) == O(n^2)

因此整个方法的复杂性将更接近O(n^2) 而不是O(n)。如链接问题中所述,使用indexOf() 的更高效、更复杂的实现可以轻松降低复杂性。

如果我们看算法复杂度,那么方法是O(n),因为indexOf() 是限制元素并且存在O(n) 的实现。但是,如果我们查看运行时复杂性,将其视为实现而不是算法,那么运行时将是O(n^2)


(旁注:我认为应该是(str1 + str1).indexOf(str2),而不是(str1 + str2).indexOf(str2)。但这并没有显着改变复杂性,也不是这个答案的重点)

【讨论】:

  • 很棒的见解,非常感谢。如上所述,我说错了,实际上只是在寻找程序的算法复杂性,听起来我的假设是正确的。同样,您的回答是否也适用于空间复杂度?
  • 或者,我应该说,由于除了使用 indexOf() 之外的连接,算法复杂度为 O(n^2)?在这种情况下,将连接委托给单独的操作会将整个函数减少到 O(n)?假设 O(n) 也是空间复杂度?
  • @ZapRowsdower 别忘了,O-notation 是复杂度的度量 class - 具有 2n 操作的算法与采用 @ 的算法具有相同的类987654349@ 操作(任何固定、恒定数量的ns - 运行时间随着n 的增加而线性增长)。因此,如果您有多个按顺序具有相同复杂度的操作,它们会相加,但函数仍保留在同一复杂度类中。在这种情况下,空间复杂度也将是 O(n) - 您分配的唯一真实空间是连接空间,它正好是输入大小的两倍。
猜你喜欢
  • 2020-09-25
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
相关资源
最近更新 更多