夯实算法-重复叠加字符串匹配

212 阅读3分钟

题目:重复叠加字符串匹配

给定两个字符串 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<=1041 <= a.length <= 10^4
  • 1<=b.length<=1041 <= b.length <= 10^4
  • a 和 b 由小写英文字母组成

解题思路

来个非常简单的模拟,虽然速度比不上,但是思考比较简单

使用一个StringBuilder sb作为a累加的效果,在每次累加a的时候,都与b进行比较,看b是否是sb的子串

注意sb的的最大长度,为b.length() + a.length() * 2; 因为a累加最极端情况下,第一个a的最后一个字母,与最后一个a的第一个字母参与将b作为子串,

使用KMP查找a是否是b的字串,如果返回值 >= 0 ,说明a 是 b 的字串; 当a 是 b的字串时,假设b中 b[left]...b[right]为a. 之后 从b[left-1]..b[0]开始判断是否和 a的倒叙一致,就对a进行倒叙遍历,如果出现不一致的情况,return -1, 否则遍历完a的前缀,left = 1; 之后 从b[right+1]..b[length-1]开始判断是否和 a的顺序一致,就对a进行顺序遍历,如果出现不一致的情况,return -1, 否则遍历完a的前缀,记录right(right可能大于1); 此时返回值为 left + right + 1; 当a不是b的字串时,判断b是否为a的字串。此时将a翻倍,令 c = a + a,然后使用KMP查找b是否是c的字串,返回值 = -1 , return -1;当返回值 >= 0时,判断 index 是否大于 aStr.length,判断成立说明需要两个a才能拼成b,return 2,否则return 1;

给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。 b若是a叠加若干次之后的子串。

代码实现

public int repeatedStringMatch(String a, String b) {
    int[] count = new int[26];
    //判断是否有字符k,存在于b,但不存在于a
    for (int i = 0; i < a.length(); i++) {
        count[a.charAt(i) - 'a'] ++;
    }
    for (int i = 0; i < b.length(); i++) {
        if (count[b.charAt(i) - 'a'] == 0) return -1;
    }
    //依次遍历a的每个字符
    for (int i = 0; i < a.length(); i++) {
        //当a的某个字符和b的头字符相同,开始比对
        if (a.charAt(i) == b.charAt(0)) {
            int start = i;
            int j = 0;
            while (j < b.length()) {
                if (a.charAt(start % a.length()) != b.charAt(j)) break;
                j++;
                start++;
            }
            //比对成功,输出结果
            if (j == b.length()) {
                int ans = start / a.length();
                if (start % a.length() != 0) ans++;
                return ans;
            }
        }
    }
    return -1;
}

运行结果

Snipaste_2023-06-14_23-35-43.png

复杂度分析

  • 空间复杂度:O(n)
  • 时间复杂度:O(n)

掘金(JUEJIN) 一起分享知识, Keep Learning!