leetcode 686. 重复叠加字符串匹配(KMP算法-java)

该文章介绍了一种利用KMP算法解决LeetCode686问题的方法,即找出字符串a重复叠加的最小次数,使字符串b成为其子串。通过构建大于b长度的a副本并应用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–高效字符串匹配算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值