This problem was asked by Facebook.
Given the mapping a = 1, b = 2, … z = 26, and an encoded message, count the number of ways it can be decoded.
For example, the message ‘111’ would give 3, since it could be decoded as ‘aaa’, ‘ka’, and ‘ak’.
You can assume that the messages are decodable. For example, ‘001’ is not allowed.
动态规划,很容易想到第一步解码字符个数的选择会影响后续的解码选择。
首先定义f[n], 即长度为n的字符串有多少种解码选择。
第二,状态转移方程。第一种情况是当前选择了一个字符,即s[i]。只要s[i]!= ‘0’, 就可以解码成A-I中的某个字母。
f[i] = f[i-1], s[i]!=‘0’
第二种情况是使用了两个字符,即s[i]和s[i+1]。只要s[i]!= ‘0’, s[i]和s[i+1]组成的整数不超过26。
f[i] = f[i-2], s[i]!='0’且10⋅s[i]+s[i+1]≤26
将上面的两种状态转移方程在对应的条件满足时进行累加,即可得到f[i]的值。
第三,初始化f[0] = 1, 即空字符串有1种解码选择,解码出一个空字符串。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int numDecodings(string s) {
int n = s.size();
vector<int> f(n +1);
f[0] = 1;
for(int i=1;i<=n;i++){
if(s[i-1] != '0'){
f[i] = f[i-1];
}
if (i > 1 && s[i - 2] != '0' && ((s[i - 2] - '0') * 10 + (s[i - 1] - '0') <= 26)) {
f[i] += f[i - 2];
}
}
return f[n];
}
int main()
{
string str= "119";
cout << numDecodings(str);
return 0;
}