面试题46. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串: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
思路
每个数字单独考虑,只有一种,固定为dp[0] = 1
,
往后面加一位,起码有dp[i] = dp[i-1]
,i等于数字位数,比如,两位数可以有两种,往后加一位变三位,起码可以包含两位数的不同类型,即dp[i] = dp[i-1]
,然后最后一位如果与前一位结合满足条件,就可以等同于一个数字,然后,起码包含了dp[i-2],参考上面的解释
比如,
一位数(0<=x<=9)
,肯定只有一种,dp[1] = dp[0] = 1;
两位数(01<=x<=99)
,起码dp[2] = dp[1],如果两个数字结合大于等于10且小于等于25则等同于只有一位数,则又包含了dp[i-2],即两种dp[2] = dp[1] + dp[0],大于25则不符合规则,仍是一种dp[2] = dp[1]。
…
依次类推,可知每多一位数,主要在于最后一位与前一位构成的两位数是否大于等于10且小于等于25,因为0x不符合规则。
使用动态规划,转移方程为
如果最后两位构成的数大于等于10且小于等于25
dp[i] = dp[i-1] + dp[i-2]
否则
`dp[i] = dp[i-1];`
然后,又因为我们一直使用的即是dp[i-1],dp[i-2],所以可以使用两个变量来代替即可,滚动数组。
代码
class Solution {
public:
int translateNum(int num) {
string str = to_string(num);
int n = str.size();
if (n <= 1)
return n;
int q = 1//dp[0]
int p = 1;//dp[1];
int ans;
for (int i = 2; i <= n; ++i){
if ("10"<=str.substr(i-2,2)&&"25">=str.substr(i-2,2))
ans = p + q;
else
ans = p;
q = p;
p = ans;
}
return ans;
}
};