题目地址:
https://www.lintcode.com/problem/1086/
给定两个字符串 A A A和 B B B,问 A A A重复多少次可以使得 B B B恰好是 A A A的子串。如果无论重复多少次都不行则返回 − 1 -1 −1。
先将 A A A重复若干次使得长度不少于 B B B的长度,接着判断 B B B是否是子串,如果不是,则再重复一次,如果还不是则返回 − 1 -1 −1。判断子串可以用KMP算法,参考https://blog.csdn.net/qq_46105170/article/details/113805346。代码如下:
public class Solution {
/**
* @param A: a string
* @param B: a string
* @return: return an integer
*/
public int repeatedStringMatch(String A, String B) {
// write your code here
StringBuilder a = new StringBuilder(A);
char[] b = B.toCharArray();
int res = 1;
while (a.length() < B.length()) {
a.append(A);
res++;
}
if (index(a.toString().toCharArray(), b) != -1) {
return res;
}
a.append(A);
res++;
if (index(a.toString().toCharArray(), b) != -1) {
return res;
}
return -1;
}
private int index(char[] s, char[] p) {
int[] next = buildNext(p);
for (int i = 0, j = 0; i < s.length; ) {
if (j == -1 || s[i] == p[j]) {
i++;
j++;
} else {
j = next[j];
}
if (j == p.length) {
return i - j;
}
}
return -1;
}
private int[] buildNext(char[] p) {
int[] next = new int[p.length];
for (int i = 0, j = next[0] = -1; i < p.length - 1; ) {
if (j == -1 || p[i] == p[j]) {
j++;
i++;
next[i] = p[i] != p[j] ? j : next[j];
} else {
j = next[j];
}
}
return next;
}
}
时间复杂度 O ( l A + l B ) O(l_A+l_B) O(lA+lB),空间 O ( l B ) O(l_B) O(lB)。