Skip to content

Latest commit

 

History

History
115 lines (93 loc) · 3.81 KB

README.md

File metadata and controls

115 lines (93 loc) · 3.81 KB

Given two strings a and b, return the minimum number of times you should repeat string a so that string b is a substring of it. If it is impossible for b​​​​​​ to be a substring of a after repeating it, return -1.

Notice: string "abc" repeated 0 times is "",  repeated 1 time is "abc" and repeated 2 times is "abcabc".

 

Example 1:

Input: a = "abcd", b = "cdabcdab"
Output: 3
Explanation: We return 3 because by repeating a three times "abcdabcdabcd", b is a substring of it.

Example 2:

Input: a = "a", b = "aa"
Output: 2

Example 3:

Input: a = "a", b = "a"
Output: 1

Example 4:

Input: a = "abc", b = "wxyz"
Output: -1

 

Constraints:

  • 1 <= a.length <= 104
  • 1 <= b.length <= 104
  • a and b consist of lower-case English letters.

Related Topics:
String

Similar Questions:

Solution 1.

We try to see if A * k contains B where k is the answer. So we keep concatenating a to an empty string s until s is not shorter than b. Assume we repeated a k times.

  • If s contains b, then return k.
  • Otherwise, if s + a contains b, return k + 1.
  • Otherwise, return -1.
// OJ: https://leetcode.com/problems/repeated-string-match/
// Author: github.com/lzl124631x
// Time: O(B * (A + B))
// Space: O(A + B)
// Ref: https://leetcode.com/problems/repeated-string-match/solution/
class Solution {
public:
    int repeatedStringMatch(string a, string b) {
        int k = 1;
        string s = a;
        for (; s.size() < b.size(); ++k) s += a;
        if (s.find(b) != string::npos) return k;
        return (s + a).find(b) != string::npos ? k + 1 : -1;
    }
};

Solution 2. Rabin-Karp

We keep finding B in repeated A string using Rabin-Karp algorithm (or Rolling Hash).

// OJ: https://leetcode.com/problems/repeated-string-match/
// Author: github.com/lzl124631x
// Time: O(A + B)
// Space: O(1)
class Solution {
    unsigned prime = 16777619;
    bool equal(string &a, string &b, unsigned offset) {
        for (int i = 0; i < b.size(); ++i) {
            if (a[(i + offset) % a.size()] != b[i]) return false;
        }
        return true;
    }
    pair<unsigned, unsigned> hashStr(string &s) {
        unsigned h = 0, p = 1, sq = prime;
        for (char c : s) h = h * prime + c;
        for (int i = s.size(); i > 0; i >>= 1) {
            if (i & 1) p *= sq;
            sq *= sq;
        }
        return { h, p };
    }
public:
    int repeatedStringMatch(string a, string b) {
        auto [hb, p] = hashStr(b);
        unsigned A = a.size(), B = b.size(), ha = 0, i = 0;
        for (; i < B; ++i) ha = ha * prime + a[i % A];
        if (ha == hb && equal(a, b, 0)) return (i + A - 1) / A;
        while (i < 2 * A + B) {
            ha = ha * prime + a[i % A] - p * a[(i - B) % A];
            ++i;
            if (ha == hb && equal(a, b, (i - B) % A)) return (i + A - 1) / A;
        }
        return -1;
    }
};