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

40 阅读2分钟

问题描述

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

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


测试样例

样例1:

输入:num = 12258 输出:5

样例2:

输入:num = 1400112 输出:6

样例3:

输入:num = 2110101 输出:10

样例4:

输入:num = 25 输出:2

样例5:

输入:num = 1023 输出:4

Solution

这里的难点就是如何进行数字的分配,比如 122 可以分成 abb , mc , bw ,如果单纯的来考虑怎么划分数字的话显然是行不通的。

仔细思考,注意到对于一个长度为 n 的字符串,假设有 f(n) 种方案,如果增加一个数字,那么我们其实只需要关注第 n 位的数字是什么,如果跟第 n+1 位能组成二位数的字母,那么就会有 f(n)+f(n-1) 种方案,否则的话,只会有 f(n) 种方案,别的地方是对最终方案没有影响的.

那么就能够转化到动态规划上了,可以从第 n 位逐渐向前转换成子问题,并且状态转移方程在上面已经给出了.

初始状态:没有字母跟有一个字母都是一种方案 dp[0]=dp[1]=1

Java代码实现
 import java.util.Arrays;
 ​
 public class Main {
     public static int solution(int num) {
         // Please write your code here
         String s = String.valueOf(num);
         int n = s.length();
 ​
         int[] dp = new int[n+1];
         Arrays.fill(dp, 0);
         dp[0] = 1;
         dp[1] = 1;
         for(int i = 2; i <= n; i++){
             int tmp = (s.charAt(i-2) - '0') * 10 + (s.charAt(i-1) - '0');
             dp[i] = dp[i-1];
             if(tmp >= 10 && tmp <= 25) dp[i] += dp[i-2];
         }
         return dp[n];
     }
 ​
     public static void main(String[] args) {
         // You can add more test cases here
         System.out.println(solution(12258) == 5);
         System.out.println(solution(1400112) == 6);
         System.out.println(solution(2110101) == 10);
     }
 }
时空复杂度

时间复杂度: O(n)

空间复杂度: O(n)

总结与思考

这个问题是一个典型的动态规划问题,通过定义状态和状态转移方程,可以有效地计算出数字的不同翻译方法。在实现过程中,还需要注意一下边界条件的处理,例如当数字的某一位是 0 时,不能单独翻译这一位,因为 0 没有对应的字母。此外,还需要注意一下数组的初始化。