229. 小U的`chi`权值计算(经典递归题) | 豆包MarsCode AI刷题

95 阅读3分钟

229.小U的chi权值计算

题目用python通过,如有需要请用ai转义成其他代码,由于这道题代码没有太复杂,看看自己写也成。


题目:小R定义了一个字符串的权值,该权值基于字符串中所有字符'h'的位置计算。对于每个字符'h',它前面的'c'和后面的'i'都会对它贡献11的权值。小R现在手上有一个由字符'c''h''i''?'组成的字符串,其中'?'表示一个未知字符,可以被替换为'c''h''i'。小R想知道,所有可能替换方案的权值之和是多少?答案可能非常大,因此需要对10 ** 9+7取模。


解题思路:

这道题用dp来做还没思考出来, 所以只能考虑用暴力一点的递归法来做。

首先,题目是要统计每个h前边的c字符数量, 和h后边的i字符数量,这两个字符的权值都是1, 所以相当于直接统计数量加和。再对每个? 取 c h i这三个字符的每一种情况下, 权值的和加和, 得到最终答案。 直接干。让marscode帮我们生成代码。
但是毫无疑问, 豆包生成的代码又是一个没有通过, 即使把正确解答的思路已经告诉了豆包。


那就自己写。 首先我们要先考虑每个 ? 分别改成 c h 和 i 这三个字符之后, 生成的字符串, 这对于回溯法来说很容易生成, 之后再对每个串做匹配算权值, 最后将权值加和, 别忘了模10 ** 9 + 7 哦。

这样的话我们需要两步,第一步来生成所有可能的字符串, 第二步用来计算字符串的权值。

第一步生成字符串的dfs函数:

参数:
i:当前处理的字符索引。 str:当前生成的字符串。 递归终止条件:当 i 达到字符串 s 的长度时,调用 calculate_weight 计算当前字符串的权值并返回。

递归过程: 如果当前字符 s[i] 是 '?',则尝试将其替换为 'c''h', 或 'i',并递归调用 dfs 处理下一个字符。 如果当前字符 s[i] 不是 '?',则直接将当前字符添加到 str 中,并递归调用 dfs 处理下一个字符。

第二步,计算字符串的权值和:

逻辑: 遍历字符串 s,对于每个字符 'h',计算其前面的 'c' 和后面的 'i' 的数量,并累加到 weight 中。每次累加后,对 10^9 + 7 取模,防止结果溢出。

solution(s)函数调用dfs(0, "")开始处理整个字符串,并返回最终结果。 而计算总和的过程在第一步里已经计算了,所以只需要返回就行了。


注意:通过递归遍历所有可能的字符串组合,并计算每种组合的权值,最终返回所有组合权值之和对10^9+7取模的结果。这种方法虽然直观,但由于递归的深度和广度,可能会导致性能问题,特别是在字符串较长或'?'较多的情况下。

通过代码:

def solution(s: str) -> int:
    MOD = 10**9 + 7

    def dfs(i, str):
        if i == len(s):
            return calculate_weight(str)

        if s[i] == '?':
            total_weight = 0
            for char in 'c''h''i':
                total_weight += dfs(i + 1, str + char)
                total_weight %= MOD
            return total_weight
        else:
            return dfs(i + 1, str + s[i])

    def calculate_weight(s: str) -> int:
        weight = 0
        for i in range(len(s)):
            if s[i] == 'h':
                weight += s[:i].count('c') + s[i+1:].count('i')
                weight %= MOD
        return weight

    return dfs(0, "")