**一刷12.14 **
二刷12.15
解法:动态规划
思想:
●状态定义:dp[i]
代表以Xi
为结尾的数字的翻译方案数量
●转移方程:
若Xi
和Xi-1
两位数字可以合在一起被翻译,那么dp[i] = dp[i - 1] + dp[i - 2]
,因为两位连起来翻译和Xi
单独翻译得到的结果是完全不同的,所以可以相加。
否则dp[i] = dp[i - 1]
,必须单独翻译当前位,所以没有变化
●初始状态:dp[0] = dp[1] = 1
,即无数字和第一位数字的翻译方法为1
●返回值:dp[n] n为num的位数
复杂度:
●时间:O(N)
●空间:O(N),str_num和dp数组各使用O(N)
代码:
class Solution {
public:
int translateNum(int num) {
string str_num = to_string(num);
int size_num = str_num.size();
vector<int>dp(size_num + 1, 0);
dp[0] = 1, dp[1] = 1;
for(int i = 2; i <= size_num; ++i){
string str_subtwo = str_num.substr(i - 2, 2);
if(str_subtwo <= "25" && str_subtwo >= "10")
dp[i] = dp[i - 1] + dp[i - 2];
else
dp[i] = dp[i - 1];
}
return dp[size_num];
}
};
改进:压缩空间到O(1)
只用到dp[i - 1]
和dp[i - 2]
class Solution {
public:
int translateNum(int num) {
string str_num = to_string(num);
int num_size = str_num.size();
//令third = 1可以在位数为1不进入循环时直接返回third
int first = 1, second = 1, third = 1;
//每一轮迭代滚动一下,获取新的third,然后first和second向后滚动
for(int i = 2; i <= num_size; ++i){
string str_subtwo = str_num.substr(i - 2, 2);
if(str_subtwo <= "25" && str_subtwo >= "10")
third = first + second;
else
third = second;
first = second;
second = third;
}
return third;
}
};