每日一题——把数字翻译成字符串

877 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目介绍

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

示例 1:

输入: 12258 输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

提示:

0 <= num < 231

思路:

这是一道典型的动态规划题目。对于一个数 num[i],我们有两种选择:

  • 只翻译自己;
  • 和前面的数字组合翻译,前提是组合的数在 10-25之间。

状态表示:dp[i]表示前i个数字的翻译的方法数。

状态计算:

我们可以分成两种情况:

  • 单独翻译自己,这时最后一个数组单独翻译,它的方法数和1234是一样的,那么计算公式是dp[i]=dp[i - 1]

  • 和前面的数组组合翻译,这时又可以分成两种情况(这里拿1234举例子):

    • 把34看成一个整体,这时34的方法数就等于dp[i] = dp[i - 1],虽然把最后一个数字加上了,但等同于没加
    • 34组合,和12的方法数是一样的,这时dp[i] = dp[i -2];

所以最终的状态转移方程为:

if(1 < = str[i]  <= 25)
​
dp[i] = dp[i -2] + dp[i -1]  
else
dp[i] = dp[i - 1]

代码:

class Solution {
public:
    int translateNum(int num) {
        if(num == 0) return 1;
        string str=to_string(num) ;
        int length = str.size();
        int N = 100010;
        int dp[N];
        dp[0] = 1;
        dp[1] = 2;
        for(int i = 1;i < length;i ++)
        {
            // 判断能否和前面的数字组合
            if(str[i - 1] == '1' || (str[i - 1] == '2' && str[i] <= '5'))
            {
                if(i == 1) dp[1] = 2;
                else dp[i] = dp[i - 1] + dp[i - 2];
            }else{
                dp[i] = dp[i - 1];
            }
        }
        return dp[length - 1];
    }
};