【发布时间】:2018-07-01 09:05:30
【问题描述】:
我最近解决了https://www.geeksforgeeks.org/find-given-string-can-represented-substring-iterating-substring-n-times/上提出的一个问题
问题是确定是否可以通过迭代子字符串 n 次从子字符串中表示特定字符串。
例如字符串"abcabcabc"可以通过迭代子字符串"abc" 3来表示。
我想出了这个 Java 解决方案
public static boolean canForm (String str) {
if(str.isEmpty()||str.length()==1) return true;
int end;
if (str.length()%2==0) {
end = str.length()/2;
} else {
end = (str.length()-1)/2;
}
for (int i=1; i<=end; i++) {
String s = str.substring(0,i);
String compare = "";
while (compare.length()<str.length()) {
compare += s;
}
if (compare.equals(str)) return true;
}
return false;
}
问题的一个条件是解决方案为 O(n)。我的结论是 O(n) 但我不确定我的解决方案是否真的是 O(n) 或者实际上是 O(n^2) 以及为什么。
【问题讨论】:
-
如果你能解释你是如何得出它的 O(n) 的,如果有错误你最好纠正你而不是完全回答问题。
-
对于每次迭代,字符串变量“compare”部分由大小为 str.substring(0,i) 的子字符串构成。例如,字符串“abcd”将需要 4 + 2 = 6 个步骤来构建。如果我们将字符串的大小加倍为“abcdefghi”,它将是 8 + 4 + 3 + 2 步。因此,总步数将是某个常数乘以 n 减去另一个常数,例如 c*n - k。因此时间复杂度是O(n)。我想知道这个想法是否有错误,以便可以纠正它并防止我将来犯这个错误。
-
请注意,由于
substring在O(n)中运行,单独的for(...) { ... str.substring(...) ... }已经产生O(n^2)。因此请参阅Time complexity of Java's substring()。串联compare += s和compare.equals(str)也是如此。所有这些子表达式都在O(n)中运行,并与包装for-loop 一起产生O(n^2)。 -
不是答案,但您可以通过首先检查
i是否是str.length的除数来改进它 -
这是我的想法。我还想到了一个替代解决方案,它涉及旋转字符串并将旋转的字符串与原始字符串进行比较。如果它们相同,则该字符串可以由一个子字符串表示 n 次。我还想到了一个 Python 解决方案,它利用了可用于字符串的乘法运算符。我只是想确定我发布的用于学习目的的解决方案的时间复杂度。