320'icci'型字符串子序列问题 线性做法!

63 阅读2分钟

题目描述

小 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]

代码


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)