题目描述:
给定两个字符串 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 由小写英文字母组成
分析
我们简要分析,a叠加后产生的字符串s,若要包含字符串b,则b中的所有字符都必须包含在a中。也就是说,若b中出现a中未有字符,直接返回-1。再分析一下s包含字符串b的情况:(n为字符串a长度,m为字符串b长度)
- a重复了m/n:字符串a直接包含字符串b,如示例3。
- a重复了m/n+1:字符串a包含字符串b的开始部分,但结尾部分未包含,需a多重复一次包含。如:a = "ab", b = "ba"。
- a重复了m/n+2:字符串a包含字符串b的开始部分,但结尾部分未包含,需a多重复两次包含。如:a = "abc", b = "cabca"。
编码
public class RepeatedStringMatch {
public int repeatedStringMatch(String a, String b) {
boolean[] exist = new boolean[26];
for (char charA : a.toCharArray()) {
exist[charA - 'a'] = true;
}
for (char charB : b.toCharArray()) {
if (!exist[charB - 'a']){
return -1;
}
}
int count = b.length() / a.length();
StringBuilder sb = new StringBuilder(a.repeat(count));
for (int i = 0; i < 3; i++) {
if (sb.toString().contains(b)){
return count + i;
}
sb.append(a);
}
return -1;
}
}