https://leetcode.cn/problems/string-transformation/solutions/2435348/kmp-ju-zhen-kuai-su-mi-you-hua-dp-by-end-vypf/
class Solution:
def numberOfWays(self, s, t, k):
n = len(s)
c = self.kmp_search(s + s[:-1], t)
#print(c)
m = [
[c - 1, c],
[n - c, n - 1 - c]
]
m = self.pow(m, k)
return m[0][s != t]
# KMP 模板
def calc_max_match(self, s: str) -> List[int]:
match = [0] * len(s)
c = 0
for i in range(1, len(s)):
v = s[i]
while c and s[c] != v:
c = match[c - 1]
if s[c] == v:
c += 1
match[i] = c
return match
# KMP 模板
# 返回 text 中出现了多少次 pattern(允许 pattern 重叠)
def kmp_search(self, text: str, pattern: str) -> int:
match = self.calc_max_match(pattern)
match_cnt = c = 0
for i, v in enumerate(text):
v = text[i]
while c and pattern[c] != v:
c = match[c - 1]
if pattern[c] == v:
c += 1
if c == len(pattern):
match_cnt += 1
c = match[c - 1]
return match_cnt
# 矩阵乘法
def multiply(self, a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
c = [[0, 0], [0, 0]]
for i in range(2):
for j in range(2):
c[i][j] = (a[i][0] * b[0][j] + a[i][1] * b[1][j]) % (10 ** 9 + 7)
return c
# 矩阵快速幂
def pow(self, a: List[List[int]], n: int) -> List[List[int]]:
res = [[1, 0], [0, 1]]
while n:
if n % 2:
res = self.multiply(res, a)
a = self.multiply(a, a)
n //= 2
return res
快速找出text中匹配pattern的次数
找出dp递推式,需要求矩阵的k次方,k很大,使用矩阵快速幂