|
| 1 | +# [3628. 插入一个字母的最大子序列数](https://leetcode.cn/problems/maximum-subsequence-score-after-applying-operations/description/) |
| 2 | + |
| 3 | +> **日期**:2026-02-26 |
| 4 | +> **所用时间**:20min |
| 5 | +> **知识点**:动态规划 |
| 6 | +
|
| 7 | +## 1. 题目描述 |
| 8 | + |
| 9 | +给定一个仅由字符 `'L'`、`'C'`、`'T'` 组成的字符串 `s`。你可以在 `s` 的**任意位置**(包括首尾)**插入**恰好一个字符(也只能是 `'L'`、`'C'` 或 `'T'`)。 |
| 10 | + |
| 11 | +插入后,得到一个新字符串。请计算新字符串中等于 **"LCT"** 的**不同子序列**的个数,并返回在所有插入方案中,该个数的**最大值**。 |
| 12 | + |
| 13 | +**说明**:子序列不要求连续,只要相对顺序与 "LCT" 相同即算一种。两个子序列若取的下标集合不同则视为不同。 |
| 14 | + |
| 15 | +**示例 1:** |
| 16 | + |
| 17 | +- **输入**:s = "LCT" |
| 18 | +- **输出**:2 |
| 19 | +- **解释**:原串已有 1 个 "LCT"。插入一个字符后,例如在 'L' 与 'C' 之间插入 'C' 得到 "L C C T",可形成更多 "LCT" 子序列,最大为 2(或其他方案,以题目为准)。 |
| 20 | + |
| 21 | +**示例 2:** |
| 22 | + |
| 23 | +- **输入**:s = "LTT" |
| 24 | +- **输出**:1 |
| 25 | +- **解释**:原串中 "LCT" 子序列数为 0。插入 'C' 在合适位置后可得到 1 个 "LCT"。 |
| 26 | + |
| 27 | +**提示:** |
| 28 | + |
| 29 | +- `1 <= s.length <= 10^5` |
| 30 | +- `s` 仅包含 `'L'`、`'C'`、`'T'` |
| 31 | + |
| 32 | +## 2. 动态规划 |
| 33 | + |
| 34 | +原串的 "LCT" 不同子序列数用经典 DP:`f[i][j]` 表示用 `s[0..i-1]` 形成 `t[0..j-1]`(其中 `t = "LCT"`)的方案数,转移为「不选 s[i]」或「选 s[i] 匹配 t[j]」(当 `s[i]==t[j]` 时)。则原串答案为 `numDistinct(s, "LCT")`。 |
| 35 | + |
| 36 | +插入一个字符后,最大值 = 原串 "LCT" 数 + 插入带来的最大增益: |
| 37 | + |
| 38 | +1. **插入 'C'**:在某个位置插入 'C',该位置左侧的每个 'L' 与右侧的每个 'T' 都能与这个 'C' 组成新的 "LCT",增益为左侧 L 的个数 × 右侧 T 的个数。枚举插入位置,取 `max(cnt_l * cnt_t)` 即为插入 'C' 的最大增益。 |
| 39 | +2. **插入 'L'**:新 'L' 可与原串中的 "CT" 子序列组成 "LCT",增益最多为原串中 "CT" 的不同子序列数,即 `numDistinct(s, "CT")`。 |
| 40 | +3. **插入 'T'**:新 'T' 可与原串中的 "LC" 子序列组成 "LCT",增益最多为 `numDistinct(s, "LC")`。 |
| 41 | + |
| 42 | +因此答案为:`numDistinct(s, "LCT") + max( max_pos(cnt_l * cnt_t), numDistinct(s, "LC"), numDistinct(s, "CT") )`。 |
| 43 | + |
| 44 | +复杂度分析: |
| 45 | + |
| 46 | +- 时间复杂度:$O(n \cdot |t|)$,其中 $n = |s|$,$|t| = 3$,即 $O(n)$;扫描求 `cnt_l`、`cnt_t` 为 $O(n)$。 |
| 47 | +- 空间复杂度:$O(n \cdot |t|)$,即 $O(n)$(可滚动数组优化为 $O(|t|)$)。 |
| 48 | + |
| 49 | +**Python3** |
| 50 | + |
| 51 | +```python |
| 52 | +class Solution: |
| 53 | + def numOfSubsequences(self, s: str) -> int: |
| 54 | + def numDistinct(s: str, t: str) -> int: |
| 55 | + n, m = len(s), len(t) |
| 56 | + f = [[1] + [0] * m for _ in range(n + 1)] |
| 57 | + |
| 58 | + for i, c1 in enumerate(s): |
| 59 | + for j, c2 in enumerate(t): |
| 60 | + if c1 != c2: |
| 61 | + f[i + 1][j + 1] = f[i][j + 1] |
| 62 | + else: |
| 63 | + f[i + 1][j + 1] = f[i][j + 1] + f[i][j] |
| 64 | + return f[n][m] |
| 65 | + |
| 66 | + cnt_t = s.count('T') |
| 67 | + cnt_l = 0 |
| 68 | + res = 0 |
| 69 | + for c in s: |
| 70 | + if c == 'T': |
| 71 | + cnt_t -= 1 |
| 72 | + if c == 'L': |
| 73 | + cnt_l += 1 |
| 74 | + res = max(res, cnt_l * cnt_t) |
| 75 | + return numDistinct(s, "LCT") + max(res, numDistinct(s, "LC"), numDistinct(s, "CT")) |
| 76 | +``` |
0 commit comments