给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。
注意:字符串 “abc” 重复叠加 0 次是 “”,重复叠加 1 次是 “abc”,重复叠加 2 次是 “abcabc”。
示例 1:
输入:a = “abcd”, b = “cdabcdab”
输出:3
解释:a 重复叠加三遍后为 “abcdabcdabcd”, 此时 b 是其子串。
示例 2:
输入:a = “a”, b = “aa”
输出:2
示例 3:
输入:a = “a”, b = “a”
输出:1
示例 4:
输入:a = “abc”, b = “wxyz”
输出:-1
提示:
1 <= a.length <= 104
1 <= b.length <= 104
a 和 b 由小写英文字母组成
class Solution {/**字符串匹配首先想到kmp算法,但我们需要先保证能匹配成功的条件:1.b中不存在a中没有的字母2.a的长度要大于等于b(还得处理刚好相等时,再加一次复制的情况)*/int[] ne = new int[10010];public int repeatedStringMatch(String a, String b) {int n = a.length(), m = b.length();int[] cnt1 = new int[26], cnt2 = new int[26];for (int i = 0; i < n; ++i) cnt1[a.charAt(i)-'a']++;for (int i = 0; i < m; ++i) cnt2[b.charAt(i)-'a']++;//如果b中存在a中没有的字母就肯定不能匹配成功for (int i = 0; i < 26; ++i)if (cnt1[i] == 0 && cnt2[i] != 0) return -1;int count = 1; //初始肯定得复制1次String s = a;int k = n;while (n < m) { //当s长度小于b长度就一直复制s = s + a; //复制sn += k;count++;}boolean isTrue = matching(s,b);if (isTrue) return count;/**为什么还要匹配一次?因为存在"abcd""cdabcdab"这种样例 得再复制尝试一次*/count++;s = s + a;if (matching(s,b)) return count;return -1;}//kmp算法public boolean matching(String s1, String s2) {int n = s1.length(), m = s2.length();s1 = " " + s1;s2 = " " + s2;//求nextfor (int i = 2, j = 0; i <= m; ++i) {while (j > 0 && s2.charAt(i) != s2.charAt(j+1)) j = ne[j];if (s2.charAt(i) == s2.charAt(j+1)) j++;ne[i] = j;}//匹配过程for (int i = 1, j = 0; i <= n; ++i) {while (j > 0 && s1.charAt(i) != s2.charAt(j+1)) j = ne[j];if (s1.charAt(i) == s2.charAt(j+1)) j++;if (j == m) return true;}return false;}}
