数字翻译成字符串的可能性 | 豆包MarsCode AI刷题

86 阅读3分钟

题目内容

小M获得了一个任务,需要将数字翻译成字符串。翻译规则是:0对应"a",1对应"b",依此类推直到25对应"z"。一个数字可能有多种翻译方法。小M需要一个程序来计算一个数字有多少种不同的翻译方法。

例如:数字 12258 可以翻译成 "bccfi", "bwfi", "bczi", "mcfi" 和 "mzi",共5种方式。

题目分析

这道题的主要思想是用动态规划求解方案数,用 AI 是基本可以直接得到答案的。但是我在使用 AI 时,它很奇怪地认为 0 不能翻译成字符?

定义状态

我们定义一个数组 dp,其中 dp[i] 表示前 i 个数字的翻译方法数量。注意,dp[0] 初始化为 1,因为空字符串有 1 种翻译方法。

状态转移

dp[i] 的值可以通过以下两种情况来计算:

  1. 当前数字一定可以单独翻译成一个字母

    • dp[i] 可以加上 dp[i-1]
  2. 当前数字和前一个数字可以组合翻译成一个字母

    • 如果当前数字和前一个数字的组合(即 num_str[i-2:i])在 10 到 25 之间,那么它们可以组合翻译成一个字母,dp[i] 可以加上 dp[i-2]

通过动态规划的方法,我们可以以 O(n)O(n) 的时间复杂度有效地计算出数字的不同翻译方法数量。

状态转移过程示例

让我们通过一个具体的例子来理解状态转移过程:

假设输入数字为 12258

数字112122122512258
dp[i]112355
  • 初始状态dp[0] = 1(空字符串有 1 种翻译方法)

  • 第一个数字 1

    • 可以单独翻译成 "b",所以 dp[1] = dp[0] = 1
  • 第二个数字 2

    • 可以单独翻译成 "c",所以 dp[2] = dp[1] = 1
    • 可以和前一个数字 1 组合翻译成 "l"(12),所以 dp[2] += dp[0] = 1 + 1 = 2
  • 第三个数字 2

    • 可以单独翻译成 "c",所以 dp[3] = dp[2] = 2
    • 可以和前一个数字 2 组合翻译成 "w"(22),所以 dp[3] += dp[1] = 2 + 1 = 3
  • 第四个数字 5

    • 可以单独翻译成 "f",所以 dp[4] = dp[3] = 3
    • 可以和前一个数字 2 组合翻译成 "z"(25),所以 dp[4] += dp[2] = 3 + 2 = 5
  • 第五个数字 8

    • 可以单独翻译成 "i",所以 dp[5] = dp[4] = 5
    • 不能和前一个数字 5 组合翻译成一个字母(因为组合 58 不在 10 到 25 之间),所以 dp[5] 不变。

最终,dp[5] 的值为 5,表示数字 12258 有 5 种不同的翻译方法。

参考代码

def solution(num):
    # 将数字转换为字符串以便于处理
    num_str = str(num)
    n = len(num_str)
    
    # 初始化动态规划数组
    dp = [0] * (n + 1)
    
    # 初始条件:空字符串有1种翻译方法
    dp[0] = 1
    
    # 遍历字符串
    for i in range(1, n + 1):
        # 当前数字可以单独翻译成一个字母
        dp[i] = dp[i-1]
        
        # 如果当前数字和前一个数字可以组合翻译成一个字母
        if i > 1 and '10' <= num_str[i-2:i] <= '25':
            dp[i] += dp[i-2]

    return dp[n]