229小U的chi权值计算

问题描述

给定一个由字符'c''h''i''?'组成的字符串,其中'?'可以替换为'c''h''i'。定义字符串的权值基于所有字符'h'的位置计算。对于每个'h',其前面的'c'和后面的'i'都会对其贡献 1 的权值。求所有可能替换方案的权值之和,结果对 (10^9 + 7) 取模。

解题思路

  1. 统计未知字符:首先统计字符串中 ? 的总数,用 cnt 表示。
  2. 前缀计数
    • prec 记录当前位置前面的 c 数量。
    • pre 记录前面 ? 的数量。
  3. 后缀计数
    • sufi 记录当前位置后面的 i 数量。
    • suf 记录后面 ? 的数量。
  4. 遍历字符串
    • 对于每个字符:
      • 如果是 c,则增加 prec
      • 如果是 i,则减少 sufi
      • 如果是 h,计算其贡献:
        • 固定 h 的贡献为 prec + sufi,乘以当前 ? 的排列组合数。每个 ? 都可以替换成 chi 这三种字符,所以总共的替换方案为 pow(3, cnt, mod)。因此前面的 ci 的贡献为 pow(3, cnt, mod) * (prec + sufi)
        • 考虑前面的 ? 替换为 c 和后面的 ? 替换为 i 的情况。前面的 ? 替换成 c 也有贡献,一个 ?pow(3, cnt - 1, mod) 种情况下可以替换成 c,而当前位置前面共有pre?,所以前面的 ? 的贡献为 pre * pow(3, cnt - 1, mod)。后面的 ? 同理为 suf * pow(3, cnt - 1, mod)
      • 如果是 ?,考虑其替换为 h 的情况,类似地计算贡献,并更新 presuf。当前的 ? 已经替换成了 h,所以后面的 ? 的贡献为 suf * pow(3, cnt - 2, mod)。前面的 ? 同理为 pre * pow(3, cnt - 2, mod)
  5. 取模:最终结果对 (10^9 + 7) 取模。

代码实现

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)
def solution(s: str) -> int:
pre = 0
cnt = suf = s.count('?')
prec = 0
sufi = s.count('i')
res = 0
for i in range(len(s)):
if s[i] == 'i':
sufi -= 1
elif s[i] == 'c':
prec += 1
elif s[i] == "h":
res = (res + pow(3, cnt, mod) * (prec + sufi) + pre * pow(3, cnt - 1, mod) + suf * pow(3, cnt - 1, mod)) % mod
else:
suf -= 1
res = (res + pow(3, cnt - 1, mod) * (prec + sufi) + pre * pow(3, cnt - 2, mod) + suf * pow(3, cnt - 2, mod)) % mod
pre += 1
return res



if __name__ == '__main__':
print(solution("ch?hi") == 16)
print(solution("ccch") == 3)
print(solution("c?i") == 2)

复杂度分析

  • 时间复杂度:(O(n)),其中(n)是字符串的长度。(实现中可以预处理快速幂的结果,使每步计算都是(O(1))的时间复杂度)
  • 空间复杂度:(O(1)),只使用了常数额外空间。

229小U的chi权值计算
https://kongshuilinhua.github.io/2024/12/27/229小U的chi权值计算/
作者
FireFLy
发布于
2024年12月27日
许可协议