You are given two strings s
and t
of equal length n
. You can perform the following operation on the string s
:
Remove a suffix of
s
of lengthl
where0 < l < n
and append it at the start ofs
.For example, let
s = 'abcd'
then in one operation you can remove the suffix'cd'
and append it in front ofs
makings = 'cdab'
.
You are also given an integer k
. Return the number of ways in which s
can be transformed into t
in exactly k
operations.
Since the answer can be large, return it modulo 10^9 + 7
.
Example 1:
```txt
Input: s = "abcd", t = "cdab", k = 2
Output: 2
Explanation:
First way:
In first operation, choose suffix from index = 3, so resulting s = "dabc".
In second operation, choose suffix from index = 3, so resulting s = "cdab".
Second way:
In first operation, choose suffix from index = 1, so resulting s = "bcda".
In second operation, choose suffix from index = 1, so resulting s = "cdab".
```
Example 2:
```txt
Input: s = "ababab", t = "ababab", k = 1
Output: 2
Explanation:
First way:
Choose suffix from index = 2, so resulting s = "ababab".
Second way:
Choose suffix from index = 4, so resulting s = "ababab".
```
Constraints:
2 <= s.length <= 5 * 10^5
1 <= k <= 10^15
s.length == t.length
s
andt
consist of only lowercase English alphabets.
字符串转换
题目
You are given two strings s
and t
of equal length n
. You can perform the following operation on the string s
:
- Remove a suffix of
s
of lengthl
where0 < l < n
and append it at the start ofs
.
For example, lets = 'abcd'
then in one operation you can remove the suffix'cd'
and append it in front ofs
makings = 'cdab'
.
You are also given an integer k
. Return the number of ways in which s
can be transformed into t
in exactly k
operations.
Since the answer can be large, return it modulo 10^9 + 7
.
Example 1:
1 | Input: s = "abcd", t = "cdab", k = 2 |
Example 2:
1 | Input: s = "ababab", t = "ababab", k = 1 |
Constraints:
-
2 <= s.length <= 5 * 10^5
-
1 <= k <= 10^15
-
s.length == t.length
s
andt
consist of only lowercase English alphabets.
题解
方法一:
思路
综合题:字符串匹配,动态规划计数,常系数递推式转化矩阵快速幂优化。
设s和t的长度都是n。
观察发现,对于s每次移动共有n-1种方式。
我们可以计算这n-1种方式形成t的个数cnt。计算的方式就是在s+s[:-1]
中寻找t的出现次数。可以用各种字符串匹配算法,如kmp,字符串哈希,后缀数组等。
s总共有n种形态,实际上这n种形态中,如果s已经等于t那么就有cnt-1种方式再次转化为s,而如果s不等于t那么就有cnt种方式转化为s。这是我们dp状态转移的依据;如果s已经等于t那么就有n-1-(cnt-1)=n-cnt种方式再次转化为非s,而如果s不等于t那么就有n-1-cnt种方式转化为非s。这是我们dp状态转移的依据;
设状态$f_{i,j}$为进行i次操作后是否(j=1是,j=0否)成为t。
$f_{i, 0} = f_{i-1, 0}\times (n-1-cnt) + f_{i-1, 1}\times (n-cnt)$
$f_{i, 1} = f_{i-1, 0}\times cnt + f_{i-1, 1}\times (cnt-1)$
将递推式改为矩阵形式。
$\left[ \begin{array}{cc} f_{i, 0} & f_{i,1} \end{array} \right] = \left[ \begin{array}{cc} f_{i-1, 0} & f_{i-1,1} \end{array} \right] \left[ \begin{array}{cc} n-cnt-1 & cnt \ n-cnt & cnt-1 \end{array} \right]$
利用矩阵快速幂,求矩阵k次幂,只需$O(logk)$次矩阵乘法
$\left[ \begin{array}{cc} f_{k, 0} & f_{k,1} \end{array} \right] = \left[ \begin{array}{cc} f_{0, 0} & f_{0,1} \end{array} \right] \left[ \begin{array}{cc} n-cnt-1 & cnt \ n-cnt & cnt-1 \end{array} \right]^k$
代码
1 |
|