Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1.
For example, with A = "abcd" and B = "cdabcdab".
Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").
Note:
The length of
The length of
A
and B
will be between 1 and 10000.为满足包含B的条件,A最多重复的次数不会超过B.length() + A.length() * 2
Solution #1, 暴力解
注意返回时的count的计算
O(m * n)
class Solution { public int repeatedStringMatch(String A, String B) { String s = A; while (s.length() <= B.length() + A.length()) { s += A; } for (int i = 0; i < s.length() - B.length() + 1; i++) { String sub = s.substring(i, i + B.length()); if (sub.equals(B)) { return (i + B.length() + A.length() - 1) / A.length(); } } return -1; } }
Solution #2, 典型的KMP
理解的要点
1. 找每个点的longest proper preffix == longest proper suffix (proper的意思是string本身不能算*ffix)
2. preprocess里是pattern自己比自己。主方法里是pattern对比A。2者的原理其实是一样的。
3. table里存的是proper的长度
class Solution { public int repeatedStringMatch(String A, String pattern) { int i = 0, j = 0; int[] table = preprocess(pattern); String s = A; while (s.length() < pattern.length() + A.length()) { s += A; } while (i < s.length()) { if (s.charAt(i) == pattern.charAt(j)) { j++; i++; if (j == pattern.length()) break; }else if (j > 0) { j = table[j - 1]; }else { i++; } } System.out.println(i); if (i == s.length()) return -1; return (i + A.length() - 1) / A.length(); } private int[] preprocess(String s) { int[] table = new int[s.length()]; int j = 0, i = 1; while (i < s.length()) { if (s.charAt(j) == s.charAt(i)) { table[i] = j + 1; j++; i++; }else if (j > 0) { j = table[j - 1]; }else { i++; } } return table; } }