把数字翻译成字符串(Python and C++解法) 题目: 思路: Python解法: C++解法:

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

示例 1:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof

思路:

可使用递归或动态规划解决该问题,它们的区别:

  • 递归是自上而下解决问题,然后等待从下面返回上来的结果;
  • 动态规划是自下而上解决问题,从已知的 base case 出发,存储前面的状态,迭代出最后的结果;

此处使用动态规划解法:

  定义状态:以第 i 位结尾的前缀串翻译的方案数。

  转移方程思路:假设翻译字符串的第 i 位置:可以单独作为一位来翻译;如果第 i−1 位和第 i位组成的数字在 10 到 25 之间,可以把这两位连起来翻译。可以用 f(i) 表示以第 i 位结尾的前缀串翻译的方案数,然后考虑第 i 位单独翻译和与前一位连接起来再翻译对 f(i)的贡献。单独翻译对 f(i)的贡献为 f(i - 1);如果第 i−1 位存在,并且第 i−1 位和第 i位形成的数字 x满足 10≤x≤25(如00, 01, 02,35, 99无法被翻译),那么就可以把第 i−1 位和第 i位连起来一起翻译,对 f(i)的贡献为 f(i - 2),否则为 0。

注意1:

  如果只翻译自己,比如 12345,如果 5单独翻译,那么方法数与 1234 是一样的,dp(i)=dp(i−1)。

注意2:

  由于当前 dp 项只和它前面两项有关,无需用数组存储所有的 dp 项,可用变量去存状态值,在迭代中更新变量,这样空间复杂度优化到 O(1),在C++解法中采用这种做法。另外,由于翻译的对称性,且C++中string的只能取从第i位开始向后的子串,所以采用从右向左的翻译顺序。(python解法中为从左向右)

Python解法:

 1 class Solution:
 2     def translateNum(self, num: int) -> int:
 3         stred = str(num)  # 数字转字符串方法,str(2) = '2'
 4         Len = len(stred)
 5         dp = [0] * (Len+1)  # 备忘录,避免重复计算
 6         dp[0] = 1
 7         dp[1] = 1
 8         for i in range(2, Len+1):  # 从左到右翻译
 9             temp = int(stred[i-2] + stred[i-1])  # 字符串转数字方法,int('2') = 2
10             if temp >= 10 and temp <= 25:
11                 dp[i] = dp[i-1] + dp[i-2]
12             else:
13                 dp[i] = dp[i-1]
14         return dp[Len]

C++解法:

 1 class Solution {
 2 public:
 3     int translateNum(int num) {
 4         string stred = to_string(num);  // C++数字转字符串方法
 5         int prepredpi = 1, predpi = 1, dpi;
 6         if(stred.size() == 1)
 7             return 1;
 8         for(int i = stred.size()-2; i >= 0; i--) {  // 从右向左翻译
 9             string preSubstr = stred.substr(i, 2);  // 抽取从i位置开始向后的2个字符的子串
10             if(preSubstr >= "10" && preSubstr <= "25")
11                 dpi = predpi + prepredpi;
12             else
13                 dpi = predpi;
14             prepredpi = predpi;
15             predpi = dpi;
16         }
17         return dpi;
18     }
19 };