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可以翻译成A,2翻译成B.....26翻译成Z,所以12可以翻译成AB,或者L;27只能翻译成BG,40则没办法翻译。
解析:这是一个简单的DP问题,假设F(n)是前面n个字符可以翻译的方法数,那么当第n+1位字符加入进来后有几种翻译方法呢,这与第n位和第n+1位两个字符组成的数字有关系,我们记录这个数字为tmp;
这个时候要分情况来讨论:
情况1:第n+1个字符为‘0’,在这种情况下,第n+1位字符不能单独翻译,只能跟第n位字符连起来一起翻译。此时,tmp的取值只能为0,10,20,30,40,50,60,70,80,90,很明显只有10,20能翻译出来,所以这个时候的F(n+1) = F(n-1),而其他情况下F(n+1) = 0;
情况2:第n+1个字符不为‘0’,在这种情况下时,第n+1位首先可以单独翻译,所以F(n+1) = F(n) + X;那么这个X要怎么确定呢?还是要看tmp的值,如果tmp的值大于26,说明第n+1位和第n位不能连起来翻译,此时 F(n+1) = F(n);当10<tmp<=26时,这个时候说明第n+1位和第n位可以连起来翻译,F(n+1) = F(n) + F(n-1);当tmp<10的时候,说明第n+1位和第n位不能连起来翻译,此时 F(n+1) = F(n);
代码实现:
public class Solution
{
public int NumDecodings(string s)
{
if (s.Length == 0 || s[0] == '0')
return 0;
int[] ret = new int[s.Length + 1];//防止类似于10,20的情况出现,需要多申请一个空间
ret[0] = 1;
ret[1] = 1;
for (int i = 1; i < s.Length; i++)
{
int tmp = Convert.ToInt32(s.Substring(i - 1, 2));
if (s[i] == '0')
{
if (tmp > 26 || tmp == 0)
return 0;
else
ret[i + 1] = ret[i - 1];
}
else
{
if (s[i - 1] == '0' || tmp > 26)
ret[i + 1] = ret[i];
else
ret[i + 1] = ret[i] + ret[i - 1];
}
}
return ret[s.Length];
}
}