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

83 阅读3分钟

数字翻译成字符串的可能性

问题描述

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

测试样例

样例1:

输入:num = 12258
输出:5

样例2:

输入:num = 1400112
输出:6

样例3:

输入:num = 2110101
输出:10

样例4:

输入:num = 25
输出:2

样例5:

输入:num = 1023
输出:4

解题思路

这个问题可以通过动态规划来解决:用一个数组 dp 来记录从数字开头到当前位置有多少种翻译方法

动态规划其实就是 用小问题的答案,来推导大问题的答案。我们可以按以下步骤逐步解决:

  1. 如果数字是空的,没有翻译方法,所以答案是0

  2. 如果数字只有1位,比如 "5",它只能翻译成一个字母("f"),所以答案是1

  3. 当数字有多位时,比如 "122",我们从左到右一位一位地检查:

    • 看当前数字(最后一位)能不能单独翻译
    • 看当前数字和前一位数字能不能合并翻译
  4. 每次把这些方法数加起来,就得到前面所有数字能翻译的总方法数

具体例子

对于数字  12258  的翻译过程:

  1. 开始时,1 只能单独翻译为 b,方法数是1

  2. 读到 12 时:

    • 2 可以单独翻译,继承前面的1种方法
    • 12 可以合并翻译,这是另一种方法
    • 所以到 12 为止,方法数是1(b+b)+ 1(m)= 2
  3. 读到 122 时:

    • 最后一位 2 可以单独翻译,继承前面2种方法
    • 最后两位 22 也可以合并翻译,这又是2种方法
    • 所以到 122 为止,方法数是2+2=4
  4. 继续到 1225 时:

    • 最后一位 5 可以单独翻译,继承前面4种方法
    • 最后两位 25 可以合并翻译,这又是4种方法
    • 所以到 1225 为止,方法数是4+4=8
  5. 最后到 12258 时:

    • 最后一位 8 可以单独翻译,继承前面8种方法
    • 最后两位 58 超出了范围,不能合并翻译
    • 所以到 12258 为止,方法数是8+0=8

动态规划

dp 定义:用 dp[i] 表示数字从第 0 位到第 i 位的子串可以翻译的不同方式数

状态转移方程:

  • 单独翻译当前数字: dp[i] += dp[i-1]
  • 如果与前一个数字组成一个两位数,且该两位数在范围 10-25 内,则 dp[i] += dp[i-2]

则最后的答案为: dp[n]

代码实现:使用Python举例

def solution(num):
    # 转成字符串以便逐位处理
    num_str = str(num)
    n = len(num_str)
    
    # 边界情况
    if n == 0:
        return 0
    if n == 1:
        return 1
    
    # 初始化dp数组
    dp = [0] * (n + 1)
    dp[0] = 1
    dp[1] = 1
    
    # 动态规划求解
    for i in range(2, n + 1):
        # 单独翻译当前数字
        dp[i] += dp[i-1]
        
        # 与前一个数字组成两位数
        two_digit = int(num_str[i-2:i])  # 两位数
        if 10 <= two_digit <= 25:
            dp[i] += dp[i-2]
    
    return dp[n]

复杂度分析:

  • 时间复杂度O(n),其中 n 是数字的位数,因为我们遍历了一遍数字
  • 空间复杂度O(n),用于存储 DP 数组