A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
一维动态规划。算法如下:
1. if string is empty, return 0;
2. two variables, prev: 空串的解码方式(初始为1); cur: s[0..0]的解码方式(如果s[0]不为0, 初始为1)。
3. 从i = 1 ....n-1
1) 如果s[i]为‘0’, 则不能单独组成一个字母。然后继续判断s[i-1],如果s[i-1]为1或者2。则s[i-1]和s[i]共同组成一个字母,更新cur为prev(s[0...i-2]的解码种类), 否则cur = 0,无法解码。
2) 如果s[i]不为‘0’,且s[i-1]为‘1’或‘2’, 则可以s[i]单独组成一个字母或者s[i-1]s[i]组成一个字母。 更新cur为prev+cur。如果s[i-1]不为1或者2,则只能s[i]单独组成一个字母,cur保持不变。
代码如下:
class Solution {
public:
int numDecodings(string s) {
const int n = s.size();
if(n == 0) return 0;
int prev = 1;
int cur = s[0]=='0'?0:1;
int tmp;
for(int i=1; i<n; i++)
{
if(s[i] == '0')
{
if(s[i-1] >= '3' || s[i-1] == '0') cur = 0;
else
{
tmp = cur;
cur = prev;
prev = tmp;
}
}
else
{
if(s[i-1] == '1' || (s[i-1] == '2' && s[i] <= '6'))
{
tmp = cur;
cur = cur+prev;
prev = tmp;
}
else
{
prev = cur;
}
}
}
return cur;
}
};
Updated code:
class Solution {
public:
int numDecodings(string s) {
const int n = s.size();
if(n == 0) return 0;
vector<int> f(n+1, 0);
f[0] = 1;
for(int i=1; i<=n; i++)
{
if(s[i-1] != '0')
f[i] += f[i-1];
if(i >= 2)
{
stringstream ss(s.substr(i-2, 2));
int val;
ss >> val;
if(val >= 10 && val <= 26)
f[i] += f[i-2];
}
}
return f[n];
}
};