每日一题-重复叠加字符串匹配(中等)

158 阅读1分钟

题目描述:

给定两个字符串 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;
    }
}

题目链接