题目描述
解法 dp
这题思路其实和斐波那契数列/吃糖果那题基本是一样的
分成固定一位和固定两位分析
- dp数组含义
dp[i]代表前i个数字可以构成的字符串个数
要注意两个细节
1.数字换成字符串,数字最高位对应的是字符串第一位
2.dp[0]对应的是前0个数字所以设dp数组大小应该为数字位数多少再加上1 - dp方程
因为dp[i]对应的是0~i-1 位数字所以
当以s[i - 2] s[i - 1]组成的数字在10~25之间时
dp[i] = dp[i-1] + dp[i - 2]
当以s[i - 2] s[i - 1]组成的数字不在10~25之间时
dp[i] = dp[i-1]
3.初始值
很明显dp[1] = 1, 当且仅当dp[2] = dp[1] + dp[0]时dp[0] 被用到,eg 11 此时dp[2] = 2,所以可得dp[0] = 1.
,
可得未优化的dp解法
class Solution {
public:
int translateNum(int num) {
if(num < 10) return 1;
string sNum = to_string(num);
int len = sNum.length();
vector<int> dp(len + 1);
//0的推导 如果需要用到dp[0]: dp[2] = dp[1] + dp[0] 可见dp[0]=1
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i < len + 1; i++) {
int t = (sNum[i - 2] - '0') * 10 + (sNum[i - 1] - '0');
if(t <= 25 && t >= 10)
dp[i] = dp[i - 1] + dp[i - 2];
else dp[i] = dp[i - 1];
}
return dp[len];
}
};
时间复杂度O(N)
空间复杂度O(N)
虽然还没有学习dp的优化,但是通过之前解斐波那契数列,我们能知道只需需要两个辅助变量交替前进就能代替dp数组,改进代码
class Solution {
public:
int translateNum(int num) {
if(num < 10) return 1;
string sNum = to_string(num);
int len = sNum.length();
//0的推导 如果需要用到dp[0]: dp[2] = dp[1] + dp[0] 可见dp[0]=1
int a = 1; //dp[1]
int b = 1; //dp[0]
int c;
for(int i = 2; i <= len; i++) {
int t = (sNum[i - 2] - '0') * 10 + (sNum[i - 1] - '0');
if(t <= 25 && t >= 10)
c = a + b;
else c = a;
b = a;//b为dp[i-1]
a = c;//a为dp[i]
}
return a;
}
};
时间复杂度O(N)
空间复杂度O(1)