难度中等1113收藏分享切换为英文接收动态反馈
一条包含字母
A-Z
的消息通过以下映射进行了 编码 :'A' -> "1" 'B' -> "2" ... 'Z' -> "26"要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,
"11106"
可以映射为:
"AAJF"
,将消息分组为(1 1 10 6)
"KJF"
,将消息分组为(11 10 6)
注意,消息不能分组为
(1 11 06)
,因为"06"
不能映射为"F"
,这是由于"6"
和"06"
在映射中并不等价。给你一个只含数字的 非空 字符串
s
,请计算并返回 解码 方法的 总数 。题目数据保证答案肯定是一个 32 位 的整数。
实例
输入:s = "12" 输出:2 解释:它可以解码为 "AB"(1 2)或者 "L"(12)
解题思路
f[i][0]:s[i]单独对应一个数字时,前i个字符可以组合成符号要求的数字的组合数
f[i][1]:s[i-1]和s[i]组合成两位的数字时,前i个字符可以组合成符号要求的数字的组合数
1.初始条件
f[0][0]=1;
f[0][1]=0;
2.边界情况
s[i]=='0'时,一定是两位数字的末尾——令f[i][0]=0;
s[i-1...i]转换后的数值超过26时,s[i-1]和s[i]不能组合成符合要求二位数字——令f[i][1]=0;
3.状态转移方程
f[i][0]=f[i-1][0]+f[i-1][1];
f[i][1]=f[i-1][0];
4.计算顺序
f[1][0],f[1][1]
f[2][0],f[2][1]
......
f[n-1][0],f[n-1][1]
5.结果
f[n-1][0]+f[n-1][1]
class Solution {
public:
//字符转整数
int Num(char ch){
return (ch-'1'+1);
}
int numDecodings(string s) {
int n=s.length();
vector<vector<int> > f(n,vector<int>(2,0));
if(s[0]=='0') return 0;
//初始条件
f[0][0]=1;f[0][1]=0;
for(int i=1;i<n;i++){
if(Num(s[i])==0){
f[i][0]=0;
}else{
f[i][0]=f[i-1][0]+f[i-1][1];
}
if(Num(s[i-1])>=3||((Num(s[i-1])==2)&&(Num(s[i])>=7))){
f[i][1]=0;
}else{
f[i][1]=f[i-1][0];
}
}
return f[n-1][0]+f[n-1][1];
}
};
测试结果