以下是 LeetCode 3337「字符串转换后的长度 II」的 Python3 实现,采用矩阵快速幂优化递推:

```python
from typing import List

class Solution:
    def lengthAfterTransformations(self, s: str, t: int, nums: List[int]) -> int:
        mod = 10**9 + 7
        m = 26

        # 统计初始字符串中每个字母的出现次数
        cnt = [0] * m
        for c in s:
            cnt[ord(c) - ord("a")] += 1

        # 构建 26x26 的转移矩阵
        # matrix[i][j] = 1 表示字母 i 经过一次转换可以变成字母 j
        matrix = [[0] * m for _ in range(m)]
        for i, x in enumerate(nums):
            for j in range(1, x + 1):
                matrix[i][(i + j) % m] = 1

        # 矩阵乘法(带模运算优化,跳过0元素)
        def matmul(a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
            n, p, q = len(a), len(b), len(b[0])
            res = [[0] * q for _ in range(n)]
            for i in range(n):
                for k in range(p):
                    if a[i][k]:
                        for j in range(q):
                            res[i][j] = (res[i][j] + a[i][k] * b[k][j]) % mod
            return res

        # 矩阵快速幂
        def matpow(mat: List[List[int]], power: int) -> List[List[int]]:
            # 初始化为单位矩阵
            res = [[int(i == j) for j in range(m)] for i in range(m)]
            while power:
                if power & 1:
                    res = matmul(res, mat)
                mat = matmul(mat, mat)
                power >>= 1
            return res

        # 将 cnt 转为 1x26 的行向量
        cnt = [cnt]
        # 计算转移矩阵的 t 次幂
        factor = matpow(matrix, t)
        # 行向量乘以转移矩阵的 t 次幂
        result = matmul(cnt, factor)[0]

        # 最终答案为所有字母数量之和
        return sum(result) % mod
```

核心思路

1. 状态定义:令 `f[i][j]` 表示经过 `i` 次转换后,第 `j` 个字母(`a`=0, ..., `z`=25)的个数。初始时 `f[0][j]` 就是字符串 `s` 中各字母的频次。

2. 转移矩阵:构造一个 26×26 的矩阵 `matrix`,其中 `matrix[i][j] = 1` 当且仅当字母 `i` 经过一次转换能生成字母 `j`。根据题意,字母 `i` 会生成 `nums[i]` 个后续连续字母(循环),即 `i+1, i+2, ..., i+nums[i]`(模 26)。

3. 矩阵快速幂:由于 `t` 最大可达 `10^9`,直接递推会超时。利用矩阵乘法的结合律,通过快速幂在 `O(log t × 26³)` 的时间内计算出 `matrix^t`。

4. 计算结果:初始频次向量(1×26)乘以 `matrix^t`,得到 `t` 次转换后的各字母数量,求和即为最终字符串长度。

复杂度

- 时间复杂度:`O(|s| + log t × 26³)`,其中 `|s| ≤ 10⁵`
- 空间复杂度:`O(26²)`,即常数级空间

 

更多推荐