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.
I have met a same problem in Sicily..But this version is a little difficult cause there may be some case which is illegal especially for zero number..
class Solution {
public:
inline bool is_letter(char front, char back) {
if (front >= '3' || front == '0') return false;
else if (front == '1') return true;
else if (back > '6') return false;
else return true;
}
int numDecodings(string s) {
if (s[0] == '0') return 0; // leading zero is illegal
for (int i = 1; i < s.size(); i++) if (!is_letter(s[i - 1], s[i]) && s[i] == '0') return 0; // if there is a zero like 30, if divide them, the single zero is illegal, if not, the 30 is illegal
int ans[s.size() + 1];
for(int i = 0; i < s.size() + 1; ans[i++] = 0);
ans[0] = 1;
if (is_letter(s[0], s[1]) && s[1] != '0') ans[1] = 2; // notice that zero cannot be a letter alone
else ans[1] = 1;
for (int i = 2; i < s.size(); i++)
if (s[i] == '0') ans[i] = ans[i - 2]; // then zero must combine with s[i - 1] to form a letter, the s[i - 1] is fixed(it must be combine with zero or this will be illegal)
else if (is_letter(s[i - 1], s[i])) ans[i] = ans[i - 2] + ans[i - 1]; // if s[i - 1] and s[i] can combine to stand for a letter, ans[i] = ans[i - 1](not combine) + ans[i - 2](combine)
else ans[i] = ans[i - 1];
return ans[s.size() - 1];
}
};