320'icci'型字符串子序列问题

题目描述

小 U 定义了一种特殊的字符串类型,称为 “icci” 型字符串。要满足这个类型,字符串必须具备以下条件:

  1. 它的长度为 4。
  2. 第一个和第四个字符必须是元音字母(’a’, ‘e’, ‘i’, ‘o’, ‘u’)。
  3. 第二个和第三个字符必须是辅音字母(除了元音以外的字母)。
  4. 该字符串是一个回文串。

例如,字符串 “awwa” 和 “uttu” 都是 “icci” 型字符串。现在给定一个字符串,小 U 想知道其中有多少个 “icci” 型的子序列。

题解

记录单个字符的数量、二元组的数量、三元组的数量。因为每次更新只和当前字符有关,可以在O(26)的复杂度下完成每次更新。

  1. 更新结果:

    • 如果当前字符 c 是元音,将 triplet[x] 加到结果 res 中,表示以 x 结尾的三元组可以形成有效的四元组。
  2. 更新三元组:

    • 如果当前字符 c 不是元音,对每个字母 ch,将 pairCount[ch][x] 加到 triplet[ch] 中,表示以 ch 开头、x 结尾的三元组数量增加。
  3. 更新二元组:

    • 对每个字母 ch,将 cnt[ch] 加到 pairCount[ch][x] 中,表示以 ch 开头、x 结尾的二元组数量增加。
  4. 更新字母计数:

    • 增加当前字母 x 的出现次数 cnt[x]

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

mod = int(1e9 + 7)
p = set("aeiou")
def solution(s: str) -> int:
cnt = [0] * 26 # 每个字符的计数
triplet = [0] * 26 # 以ch开头的三元组
pairCount = [[0 for _ in range(26)] for _ in range(26)] # i j 二元组
res = 0
for c in s:
x = ord(c) - ord('a')
if c in p:
res = (res + triplet[x]) % mod
if c not in p:
for ch in range(26):
triplet[ch] = (triplet[ch] + pairCount[ch][x]) % mod
for ch in range(26):
pairCount[ch][x] = (pairCount[ch][x] + cnt[ch]) % mod
cnt[x] += 1

return res

if __name__ == '__main__':
print(solution("iiaabbii") == 4)
print(solution("aekekeo") == 1)
print(solution("abcdefg") == 0)

复杂度

时间复杂度O(26n),其中 n 是字符串长度。
空间复杂度: O(26 * 26)


320'icci'型字符串子序列问题
https://kongshuilinhua.github.io/2024/12/31/320-icci-型字符串子序列问题/
作者
FireFLy
发布于
2024年12月31日
许可协议