686. 重复叠加字符串匹配

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

注意:字符串 "abc" 重复叠加 0 次是 "",重复叠加 1 次是 "abc",重复叠加 2 次是 "abcabc"。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-string-match
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

KMP

class Solution {

    private int[] getNext(String str) {
        int[] next = new int[str.length()];
        next[0] = -1;
        int i = 0, j = -1;
        while (i < str.length() - 1) {
            if (j == -1 || str.charAt(i) == str.charAt(j)) {
                if (str.charAt(++i) == str.charAt(++j)) {
                    next[i] = next[j];
                } else {
                    next[i] = j;
                }
            } else {
                j = next[j];
            }
        }
        return next;
    }

    public int repeatedStringMatch(String a, String b) {
        int[] next = getNext(b);
        int i = 0, j = 0;
        while (i - j < a.length() && j < b.length()) {
            if (j == -1 || a.charAt(i % a.length()) == b.charAt(j)) {
                i++;
                j++;
            } else {
                j = next[j];
            }
        }
        if (j != b.length()) {
            return -1;
        }
        return i % a.length() == 0 ? i / a.length() : i / a.length() + 1;
    }
}

Rabin-Karp

import java.util.Scanner;

class Solution {

    private int base = 127;

    private int mod = 1000000007;

    private int hash(String str) {
        long ret = 0;
        for (int i = 0; i < str.length(); ++i) {
            ret = (ret * base + str.charAt(i)) % mod;
        }
        return (int) ret;
    }

    private long getMaxBase(int n) {
        long ret = 1;
        for (int i = 1; i < n; ++i) {
            ret = (ret * base) % mod;
        }
        return ret;
    }

    public int repeatedStringMatch(String a, String b) {
        int goalHash = hash(b);

        long maxBase = getMaxBase(b.length());

        long curHash = 0;

        int idx = 0;

        while (idx + 1 - b.length() < a.length() && curHash != goalHash) {
            int leftBorder = idx - b.length();
            int leftVal = leftBorder < 0 ? 0 : a.charAt(leftBorder % a.length());
            curHash = (((curHash - (leftVal * maxBase) % mod + mod) * base + a.charAt(idx % a.length()))) % mod;
            idx++;
        }

        if (curHash == goalHash) {
            return idx % a.length() == 0 ? idx / a.length() : ((idx / a.length() + 1));

        }
        return -1;
    }


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            System.out.println(new Solution().repeatedStringMatch(in.next(), in.next()));
        }
    }
}
posted @ 2021-12-18 00:33  Tianyiya  阅读(51)  评论(0)    收藏  举报