题目
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
示例 1:
输入: 12258
输出: 5 解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”,“mcfi"和"mzi”
解题思路
这是一道动态规划的题目,难点在写出状态转移方程。即 S n − 1 S_{n-1} Sn−1如何到 S n S_{n} Sn( S n S_{n} Sn表示n个数字的不同解释数目)。 S n − 1 S_{n-1} Sn−1到 S n S_{n} Sn只差了一个 a n a_n an( a n a_n an表示第n个数字)。并且 a n a_n an有以下两种状态:
(1)和 a n − 1 a_{n-1} an−1组成一对。我们称为“不单身”状态。在这种情况下的组合数为 g n g_n gn。
(2)没有和 a n − 1 a_{n-1} an−1组成一对。在这种情况下的组合数为 f n f_n fn。
于是有状态转移方程:
{ f ( n ) = f ( n − 1 ) + g ( n − 1 ) , if a n 是单身 g ( n ) = f ( n − 1 ) , if a n 不是单身 \begin{cases} f(n)=f(n-1)+g(n-1), & \text {if $a_n$ 是单身} \\ g(n)=f(n-1), & \text{if $a_n$ 不是单身} \end{cases} {
f(n)=f(n−1)+g(n−1),g(n)=f(n−1),if an 是单身if an 不是单身
S n = f ( n ) + g ( n ) S_{n}=f(n)+g(n) Sn=f(n)+g(n)
简单解释就是:只有 a n − 1 a_{n-1} an−1单身还要满足一定条件(题目给的是“a[n-1]==‘1’ || (a[n-1] ==‘2’&&a[n]<‘6’”)才有可能和 a n a_n an组成cp,当然, a n a_n an也可以选择拒绝。当 a n − 1 a_{n-1} an−1不单身的时候, a n a_n an是一定单身的。
c++代码
class Solution {
public:
string a;
int f(int n){
if(n==0)return 1;
return f(n-1)+g(n-1);
}
int g(int n){
if(n==0)return 0;
if (a[n-1]=='1'||(a[n-1]=='2'&&a[n]<'6'))return f(n-1);
return 0;
}
int translateNum(int num){
if (num==0)return 1;
a= to_string(num);
int n=a.size();
return f(n-1)+g(n-1);
}
};
这里记录一下:string类是真的方便,一开始用c写还要考虑int到数组的转换,自己手写了一个转换函数,感觉蠢蠢的,string的内置函数to_string真的很好用。