题目
一条包含字母 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 位 的整数。
解法 动态规划
这是一道动态规划的问题,建了一个dp容器,dp[0] = 1; 表示空字符的边界情况, dp[i]表示到第i个位置,有多少种答案符合要求,
分为下列三种情况,
1.当前选中的字符为0
,那么他只能与前面的数字进行结合,并且两个数字要在符合要求的范围内,此时dp[i] += dp[i - 2];
2.当前选中的字符不是0,那么它一定可以单独作为一种答案,与i - 1的种种情况进行结合,则dp[i] += dp[i - 1];
3.如果当前选中的字符不是0,并且还可以与前面的字母进行结合形成一种新的情况,那么dp[i] += dp[i - 2];
附上完整代码:
class Solution {
public:
int numDecodings(string s) {
if(s[0] == '0')
return 0;
int len = s.length();
vector<int> res(len + 1, 0);
res[0] = 1;
for(int i = 1; i <= len; ++i){
if(s[i - 1] != '0')
res[i] += res[i - 1];
if(i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + s[i - 1] - '0' <= 26))
res[i] += res[i - 2];
}
return res[len];
}
};
总结
动态规划问题,好好思考转移方程!