题目:
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.
思路:
这是一道典型的一维动态规划题目,我们对递推表达式的分析如下:定义dp[i]表示s[0,i]子串的解码个数。如果s[i]的范围为0-9,那么s[i]可以独立解码,此时dp[i-1]构成了dp[i]的解的一部分;如果s[i-1, i]的范围为10-26,那么s[i-1,i]可以一起解码,此时dp[i-2]也构成了dp[i]的一部分。最终dp[i]的解由前面两部分构成。注意一旦dp[i]的递推结果为0,那么后续结果都将为0,所以此时可以提前返回结果。
代码:
class Solution {
public:
int numDecodings(string s)
{
int length = s.length();
if(length == 0)
return 0;
vector<int> dp(length, 0);
int val1, val2;
val1 = getValue(s, 0, 1);
if(val1 >= 1 && val1 <= 9)
dp[0] = 1;
else
dp[0] = 0;
if(length == 1 || dp[0] == 0)
return dp[0];
val1 = getValue(s, 1, 1);
if(val1 >= 1 && val1 <= 9)
dp[1] += 1;
val2 = getValue(s, 0, 2);
if(val2 >= 10 && val2 <= 26)
dp[1] += 1;
for(int i = 2; i < length; ++i)
{
val1 = getValue(s, i, 1);
if(val1 >= 1 && val1 <= 9)
dp[i] += dp[i-1];
val2 = getValue(s, i - 1, 2);
if(val2 >= 10 && val2 <= 26)
dp[i] += dp[i-2];
if(dp[i] == 0)
return 0;
}
return dp[length - 1];
}
private:
int getValue(const string& s, int index, int len)
{
// len can be either 1 or 2
int ret = s[index] - '0';
if(len == 2)
ret = ret * 10 + s[index+1] - '0';
return ret;
}
};