方法一:字符串遍历
理解:动态规划讲究从后往前推,想知道12258几种翻译方式需要如下思考
- 12258有几种翻译方式,5和当前位置8能否组成对应字母,这里引出形成字母的条件
- 组成的数字x必须满足10<=x<=25,小于25很好想,101>>这里的01是不能组合成新字母的;这里58不满足这个条件,不能新增翻译方式,所以12258的翻译方法数量上与1225一致
- 1225有几种?2和当前位置满足新的翻译条件。。。。
class Solution {
public:
int translateNum(int num) {
string s;s = to_string(num);
int len = s.size();
vector<int> dp(len+1,0);
dp[0] = dp[1] = 1;
for(int i =2;i<=len;++i){
//当前字符串可以和前一个字符串合并
string tmp = s.substr(i-2,2);
//tmp>="10"&&tmp<="25"
if(tmp.compare("10") >= 0 && tmp.compare("25")<= 0 ){
dp[i] = dp[i-1]+dp[i-2];
}
//不可合并
else
dp[i] =dp[i-1];
}
return dp[len];
}
};
优化:
class Solution {
public:
int translateNum(int num) {
string s = to_string(num);
int a = 1, b = 1, len = s.size();
for(int i = 2; i <= len; i++) {
string tmp = s.substr(i - 2, 2);
int c = tmp.compare("10") >= 0 && tmp.compare("25") <= 0 ? a + b : a;
b = a;
a = c;
}
return a;
}
};
方法二:数字求余
class Solution {
public:
int translateNum(int num) {
int dpl =1,dpr =1, c=1;
int l =0,r =0;
int num2 = num;
while(num>9){
r = num%10; //r =8
num /=10;//12258>>1225
l = num%10 ;//l =5
if((l*10+r)<=25&&(l*10+r)>=10){
c=dpl+dpr;
}
dpr = dpl;
dpl = c;
}
return dpl;
}
};