题目描述
小 U 定义了一种特殊的字符串类型,称为 "icci" 型字符串。要满足这个类型,字符串必须具备以下条件:
- 它的长度为 4。
- 第一个和第四个字符必须是元音字母('a', 'e', 'i', 'o', 'u')。
- 第二个和第三个字符必须是辅音字母(除了元音以外的字母)。
- 该字符串是一个回文串。
例如,字符串 "awwa" 和 "uttu" 都是 "icci" 型字符串。现在给定一个字符串,小 U 想知道其中有多少个 "icci" 型的子序列。
题解
记录单个字符的数量、二元组的数量、三元组的数量。因为每次更新只和当前字符有关,可以在O(26)的复杂度下完成每次更新。
-
更新结果:
- 如果当前字符
c是元音,将triplet[x]加到结果res中,表示以x结尾的三元组可以形成有效的四元组。
- 如果当前字符
-
更新三元组:
- 如果当前字符
c不是元音,对每个字母ch,将pairCount[ch][x]加到triplet[ch]中,表示以ch开头、x结尾的三元组数量增加。
- 如果当前字符
-
更新二元组:
- 对每个字母
ch,将cnt[ch]加到pairCount[ch][x]中,表示以ch开头、x结尾的二元组数量增加。
- 对每个字母
-
更新字母计数:
- 增加当前字母
x的出现次数cnt[x]。
- 增加当前字母
代码
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)