重复叠加字符串匹配
- leetcode 686. 重复叠加字符串匹配
- 题目描述
- KMP 算法
- 代码演示
- KMP 算法
leetcode 686. 重复叠加字符串匹配
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/repeated-string-match
题目描述
给定两个字符串 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 <= 10000
1 <= b.length <= 10000
a 和 b 由小写英文字母组成
KMP 算法
首先想明白一个问题,如果叠加后含有b,那么起始位置,一定是在a的某一个位置.
因此我们可以先复制出长度大于b字符串长度的字符串,然后根据kmp算法,看b是否是a叠加后的字串,就可以得出,得出需要复制的次数(在叠加时,记录叠加的次数).
代码演示
/*** leetcode 686. 重复叠加字符串匹配* @param a* @param b* @return*/public int repeatedStringMatch(String a, String b) {StringBuilder sb = new StringBuilder();int time = 0;//当长度大于b 的长度时,就退出while (sb.length() < b.length()){time++;sb.append(a);}sb.append(a);int indexOf = getIndexOf(sb.toString(), b);if (indexOf == -1){return -1;}return indexOf + b.length() > a.length() * time ? time + 1 : time;}/*** 判断s2 是否是 s1的子串. 返回出现的第一个字母的下标* @param s1* @param s2* @return*/public int getIndexOf(String s1, String s2) {if (s1 == null || s2 == null || s1.length() == 0 || s1.length() < s2.length()){return -1;}char[] str1 = s1.toCharArray();char[] str2 = s2.toCharArray();int[] next = getNextArray(str2);int x = 0;int y = 0;while (x < str1.length && y < str2.length){if (str1[x] == str2[y]){//相等时 去下一个位置去比较x++;y++;} else if (next[y] == -1) {x++;}else {y = next[y];}}return y == str2.length ? x - y : -1;}/*** 前缀和后缀相等的长度数组* @param str* @return*/public int[] getNextArray(char[] str){if(str.length == 1){return new int[]{-1};}int n = str.length;int[] next = new int[n];next[0] = -1;next[1] = 0;int i = 2;int hc = 0;while (i < n){if (str[i - 1] == str[hc]){next[i++] = ++hc;} else if (hc > 0) {hc = next[hc];}else {next[i++] = 0;}}return next;}
KMP 算法
KMP–高效字符串匹配算法