0686. 重复叠加字符串匹配
大约 4 分钟
---
0686. 重复叠加字符串匹配
- 标签:字符串、字符串匹配
- 难度:中等
题目链接
题目大意
描述:给定两个字符串 a 和 b。
要求:寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。
说明:
- 字符串
"abc"重复叠加0次是"",重复叠加1次是"abc",重复叠加2次是"abcabc"。 - 。
- 。
a和b由小写英文字母组成。
示例:
- 示例 1:
输入:a = "abcd", b = "cdabcdab"
输出:3
解释:a 重复叠加三遍后为 "abcdabcdabcd", 此时 b 是其子串。- 示例 2:
输入:a = "a", b = "aa"
输出:2解题思路
思路 1:KMP 算法
假设字符串 a 的长度为 n,b 的长度为 m。
把 b 看做是模式串,把字符串 a 叠加后的字符串看做是文本串,这道题就变成了单模式串匹配问题。
我们可以模拟叠加字符串 a 后进行单模式串匹配问题。模拟叠加字符串可以通过在遍历字符串匹配时对字符串 a 的长度 n 取余来实现。
那么问题关键点就变为了如何高效的进行单模式串匹配,以及字符串循环匹配的退出条件是什么。
单模式串匹配问题:可以用 KMP 算法来做。
循环匹配退出条件问题:假设我们用 i 遍历 a 叠加后字符串,用 j 遍历字符串 b。如果字符串 b 是 a 叠加后字符串的子串,那么 b 有两种可能:
b直接是原字符串a的子串:这种情况下,最多遍历到len(a)。b是a叠加后的字符串的子串:- 最多遍历到
len(a) + len(b),可以写为while i < len(a) + len(b):,当i == len(a) + len(b)时跳出循环。 - 也可以写为
while i - j < len(a):,这种写法中i - j表示的是字符匹配开始的位置,如果匹配到len(a)时(即i - j == len(a)时)最开始位置的字符仍没有匹配,那么b也不可能是a叠加后的字符串的子串了,此时跳出循环。
- 最多遍历到
最后我们需要计算一下重复叠加字符串 a 的最小次数。假设 index 使我们求出的匹配位置。
- 如果
index == -1,则说明b不可能是a叠加后的字符串的子串,返回False。 - 如果
len(a) - index >= len(b),则说明匹配位置未超过字符串a的长度,叠加1次(字符串a本身)就可以匹配。 - 如果
len(a) - index < len(b),则说明需要叠加才能匹配。此时最小叠加次数为 。其中index代笔匹配开始前的字符串长度,加上len(b)后就是匹配到字符串b结束时最少需要的字符数,再-1是为了向下取整。 除以len(a)表示至少需要几个a, 因为是向下取整,所以最后要加上1。写成代码就是:(index + len(b) - 1) // len(a) + 1。
思路 1:代码
class Solution:
# KMP 匹配算法,T 为文本串,p 为模式串
def kmp(self, T: str, p: str) -> int:
n, m = len(T), len(p)
next = self.generateNext(p)
i, j = 0, 0
while i - j < n:
while j > 0 and T[i % n] != p[j]:
j = next[j - 1]
if T[i % n] == p[j]:
j += 1
if j == m:
return i - m + 1
i += 1
return -1
def generateNext(self, p: str):
m = len(p)
next = [0 for _ in range(m)]
left = 0
for right in range(1, m):
while left > 0 and p[left] != p[right]:
left = next[left - 1]
if p[left] == p[right]:
left += 1
next[right] = left
return next
def repeatedStringMatch(self, a: str, b: str) -> int:
len_a = len(a)
len_b = len(b)
index = self.kmp(a, b)
if index == -1:
return -1
if len_a - index >= len_b:
return 1
return (index + len(b) - 1) // len(a) + 1思路 1:复杂度分析
- 时间复杂度:,其中文本串 的长度为 ,模式串 的长度为 。
- 空间复杂度:。