AcWing 59 把数字翻译成字符串

题目描述:

给定一个数字,我们按照如下规则把它翻译为字符串:

0翻译成”a”,1翻译成”b”,……,11翻译成”l”,……,25翻译成”z”。

一个数字可能有多个翻译。例如12258有5种不同的翻译,它们分别是”bccfi”、”bwfi”、”bczi”、”mcfi”和”mzi”。

请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。

样例

输入:"12258"

输出:5

分析:

本题很容易想到dp,最容易的思路是定义dp[i]为以第i个数字为结尾的不同翻译方法数。比如12258,dp[0] = 1,dp[1] = 2,每种状态可由前面的两种状态转移得到,即dp[i-2] + dp[i-1],dp[i-2]要在s[i-1]连接s[i]符合规范时才能转移,也就是10-25之间时。也就是说,第i种状态,要么等于前一种状态,要么等于前两种状态之和。

这里具体的写法可能有所不同,因为如果定义dp[0]为以第0个字符结尾的翻译数,那么dp[1]则要考虑前两种状态,从空和从dp[0]开始转移,从空的状态总不能写dp[-1]吧。所以需要定义一个哨兵结点,就是空的状态有一种翻译方法,dp[i]表示真正以第i个字符结尾的翻译数,比如12258,字符串第一个数是1,而不是从0开始计数了。这样递推就可以往下进行了,但是要注意,此时从dp[i-2]向dp[i]转移的条件是s[i-2]和s[i-1]连起来符合规范,因为这里dp的下标比字符串的下标偏了一下。所以边界情况就是dp[0]和dp[1]都为1,进而向整个状态空间扩散。(具体编程时会发现,循环你要是从1开始,循环体内第一次遍历出现了s[-1]和dp[-1]不但没报错,结果仍然正确。访问下标为-1的数组元素不合法但是编译器并没有报错。)

class Solution {
public:
    int getTranslationCount(string s) {
        int n = s.size();
        int dp[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2;i <= n;i++){
            dp[i] = dp[i-1];
            int t = (s[i-2] - '0') * 10 + s[i - 1] - '0';
            if(t >= 10 && t <= 25)  dp[i] += dp[i-2];
        }
        return dp[n];
    }
};

猜你喜欢

转载自blog.csdn.net/qq_30277239/article/details/88532945