题目:
给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。
题目解析:这是一道典型的DP题目。
1.分析其是否为DP问题。两个条件:1.最优子结构;2.重复子问题。分析一下,以12258为例,将1和2258分离成两部分,先翻译1,在翻译2258,明显2258是在1的基础上在进行翻译,以此类推,满足上述条件,为DP问题。
2.使用状态转移方程进行描述。分析一下,以12258为例,使用上面的方法进行分割,发现当前数字和前面数字相加大于25的时候,f(n)=f(n-1);函数f(n)表示n个字符的不同翻译方法。另外一种情况稍微复杂一些,当前数字和前面数字相加小于25的时候,通过12258这个例子可能一下子看不出来,那么我们在随便举个例子,12314,列举一下,我们可以发现f(n)=f(n-1)+f(n-2)的。所以状态转换方程在两种情况下分为两个表达式。
3.选择对应的数据结构去存储或者表达这个状态方程,因为这里仅仅表示数字,所以我们可以选择一维数组进行表达。
4.有了数据结构表示的状态方程,那么我们需要进行一个初始化,通过观察发现f(n)=f(n-1)+f(n-2),是有两个提前量的,所以我们需要初始化f(0)和f(1)。
最后编写代码:
class Solution {
public:
int translateNum(int num) {
if(num == 0)
return 1;
string strs = to_string(num);
vector<int> dp(strs.size()+1,0);
dp[0] = 1;
dp[1] = 1;
strs = '0' + strs;
for(int i = 2; i < strs.size(); i++)
{
int temp = (strs[i-1] - '0')*10 + strs[i] - '0';
if(temp >= 10 && temp < 26)
{
dp[i] = dp[i-1] + dp[i-2];
}else{
dp[i] = dp[i-1];
}
}
return dp[strs.size()-1];
}
};