[LeetCode] 686. Repeated String Match 重复字符串匹配

时间:2023-03-10 06:38:59
[LeetCode] 686. Repeated String Match 重复字符串匹配

Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1.

For example, with A = "abcd" and B = "cdabcdab".

Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").

Note:
The length of A and B will be between 1 and 10000.

给2个字符串,找到字符串A需要重复的次数,使得字符串B是字符串A的子串,如果没有答案,则返回-1。

解法1:  Brute fore. a modified version of string find, which does not stop at the end of A, but continue matching by looping through A

解法2: KMP, O(n + m) version that uses a prefix table (KMP)

解法3: Rabin-Karp Algorithm

Java: 1

class Solution {
public int repeatedStringMatch(String A, String B) {
StringBuilder sb = new StringBuilder();
sb.append(A);
int count = 1;
while(sb.indexOf(B)<0){
if(sb.length()-A.length()>B.length()){
return -1;
}
sb.append(A);
count++;
} return count;
}  

Python: 1

class Solution(object):
def repeatedStringMatch(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
sa, sb = len(A), len(B)
x = 1
while (x - 1) * sa <= 2 * max(sa, sb):
if B in A * x: return x
x += 1
return -1 

Python: 3

# Time:  O(n + m)
# Space: O(1) class Solution(object):
def repeatedStringMatch(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
def check(index):
return all(A[(i+index) % len(A)] == c
for i, c in enumerate(B)) M, p = 10**9+7, 113
p_inv = pow(p, M-2, M)
q = (len(B)+len(A)-1) // len(A) b_hash, power = 0, 1
for c in B:
b_hash += power * ord(c)
b_hash %= M
power = (power*p) % M a_hash, power = 0, 1
for i in xrange(len(B)):
a_hash += power * ord(A[i%len(A)])
a_hash %= M
power = (power*p) % M if a_hash == b_hash and check(0): return q power = (power*p_inv) % M
for i in xrange(len(B), (q+1)*len(A)):
a_hash = (a_hash-ord(A[(i-len(B))%len(A)])) * p_inv
a_hash += power * ord(A[i%len(A)])
a_hash %= M
if a_hash == b_hash and check(i-len(B)+1):
return q if i < q*len(A) else q+1 return -1  

C++: 1

int repeatedStringMatch(string A, string B) {
for (auto i = 0, j = 0; i < A.size(); ++i) {
for (j = 0; j < B.size() && A[(i + j) % A.size()] == B[j]; ++j);
if (j == B.size()) return (i + j) / A.size() + ((i + j) % A.size() != 0 ? 1 : 0);
}
return -1;
}

C++: 2

int repeatedStringMatch(string a, string b) {
vector<int> prefTable(b.size() + 1); // 1-based to avoid extra checks.
for (auto sp = 1, pp = 0; sp < b.size(); ) {
if (b[pp] == b[sp]) prefTable[++sp] = ++pp;
else if (pp == 0) prefTable[++sp] = pp;
else pp = prefTable[pp];
}
for (auto i = 0, j = 0; i < a.size(); i += max(1, j - prefTable[j]), j = prefTable[j]) {
while (j < b.size() && a[(i + j) % a.size()] == b[j]) ++j;
if (j == b.size()) return (i + j) / a.size() + ((i + j) % a.size() != 0 ? 1 : 0);
}
return -1;
}

C++:

class Solution {
public:
int repeatedStringMatch(string A, string B) {
string t = A;
for (int i = 1; i <= B.size() / A.size() + 2; ++i) {
if (t.find(B) != string::npos) return i;
t += A;
}
return -1;
}
};

C++:

class Solution {
public:
int repeatedStringMatch(string A, string B) {
int m = A.size(), n = B.size();
for (int i = 0; i < m; ++i) {
int j = 0;
while (j < n && A[(i + j) % m] == B[j]) ++j;
if (j == n) return (i + j - 1) / m + 1;
}
return -1;
}
};

  

类似题目:  

[LeetCode] 459. Repeated Substring Pattern 重复子字符串模式

  

All LeetCode Questions List 题目汇总