题目

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

示例

  • 示例1

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

代码

  • dp做法
class Solution {
    public int translateNum(int num) {
        String str = String.valueOf(num);
        int len = str.length();
        if(len == 0)    return 0;
        // dp[i] 代表从 num[0] 到 num[i-1] 有多少种不同的翻译
        // 因为 dp[] 有效范围是从 [1,len]
        int[] dp = new int[len+1];
        // dp[1] = 1 : num[1-1] = num[0] 即只有一种翻译
        dp[0] = dp[1] = 1;
        for(int i = 2; i <= len; i++){
            String tempStr = str.substring(i-2,i);
            if(tempStr.compareTo("10") >= 0 && tempStr.compareTo("25") <= 0){
                dp[i] = dp[i-1] + dp[i-2];
            }else{
                dp[i] = dp[i-1];
            }
        }
        return dp[len];
    }
}

代码分析详解
转移方程
1、dp[i] 代表从 num[0]num[i-1] 有多少种不同的翻译
2、从局部来看,如果截取的两位不在 [10,25] 之间,就只有一种翻译形式,即dp[i] = dp[i-1];;如果截取的两位在 [10,25] 之间,也就意味着两位可以单独翻译,也可以合并翻译,即 dp[i] = dp[i-1] + dp[i-2];
3、仔细想想就是有条件的小青蛙跳台阶问题。

补充:关于截取字符串Java(substring) 和 C++(substr)
substring(begin,end):begin为起始下标,end为截止位置(左闭右开
substr(begin,len):begin为起始下标,len为截取长度

本文题目ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof

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

本文题目把数字翻译成字符串