一条包含字母 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 位 的整数。
class Solution {
public:
bool f(char a , char b)//判断是否合法
{
if(a > '2' || a == '0') return false;
else if(a == '2')
{
if(b > '6') return false;
else return true;
}
else return true;
}
int numDecodings(string s) {
if(s[0] == '0') return 0;
int len = s.size();
int dp[len + 1];
memset(dp , 0 , sizeof(dp));
dp[0] = 1;
for(int i = 1; i <= len; i++)
{
dp[i] = dp[i - 1];
if(i == 1) ;
else if(s[i - 1] == '0')
{
if(s[i - 2] > '2' || s[i - 2] == '0') return 0;
else dp[i] = dp[i - 2];//当前符号为0,且与前一个相连合法
}
else if(f(s[i - 2] , s[i - 1]))
{
dp[i] = dp[i] + dp[i - 2];//与前一个相连合法,方案数来自当前字符单独编译和与前一个一同编译的和
}
}
return dp[len];
}
};