1 题目描述
2 解法
2.1 暴力法:时间复杂度为O(n^2)
2.1.1 法一
将原字符串拼接一次,然后去掉第一个和最后一个字符,接着检查这个新字符串中是否包含原字符串。
class Solution {
public boolean repeatedSubstringPattern(String s) {
String str = s+s;
str = str.substring(1,str.length() - 1);
return str.contains(s);
}
}
2.1.2 法二
从长度为 1 到 n/2 的所有可能子串长度中进行枚举,对于每个子串长度,检查是否可以由该子串重复构成原字符串。如果找到了满足条件的子串长度,则返回 true;
public class Solution {
public boolean repeatedSubstringPattern(String s) {
int n = s.length();
for (int i = 1; i <= n / 2; i++) {
if (n % i == 0) {
String sub = s.substring(0, i);
boolean repeated = true;
for (int j = i; j < n; j += i) {
if (!s.substring(j, j + i).equals(sub)) {
repeated = false;
break;
}
}
if (repeated) {
return true;
}
}
}
return false;
}
}
2.2 KMP算法:时间复杂度为O(n)
class Solution {
public boolean repeatedSubstringPattern(String s) {
return kmp(s + s, s);
}
public boolean kmp(String query, String pattern) {
int n = query.length();
int m = pattern.length();
int[] fail = new int[m];
Arrays.fill(fail, -1);
for (int i = 1; i < m; ++i) {
int j = fail[i - 1];
while (j != -1 && pattern.charAt(j + 1) != pattern.charAt(i)) {
j = fail[j];
}
if (pattern.charAt(j + 1) == pattern.charAt(i)) {
fail[i] = j + 1;
}
}
int match = -1;
for (int i = 1; i < n - 1; ++i) {
while (match != -1 && pattern.charAt(match + 1) != query.charAt(i)) {
match = fail[match];
}
if (pattern.charAt(match + 1) == query.charAt(i)) {
++match;
if (match == m - 1) {
return true;
}
}
}
return false;
}
}