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.
暴力解法,超时
public int NumDecodings(string s)
{
if (s.Length == 0)
return 0;
if (s.Length ==1&&s[0]!='0')
return 1;
if (s[0] == '0')
return 0;
int tmp = s.Length == 2 ? 1 : 0;
if (s[0] == '1' || (s[0] == '2' && s[1] < '7'))
return NumDecodings(s.Substring(1)) + NumDecodings(s.Substring(2)) + tmp;
return NumDecodings(s.Substring(1));
}
动态规划:
如果当前数字为0,则前面数字必为1或者2,否则无法进行编码转换,此时只能和前面的1或者2连在一起进行编码,因此res[i] = res[i-2];
如果前面数字和前面数字的组合可以进行2种编码(分开或者和在一起),则res[i] = res[i-1] + res[i-2];
否则,当前数字必须单独进行编码转换,res[i] = res[i-1]。
public int NumDecodings(string s)
{
if (s.Length == 0 || s[0] == '0')
return 0;
int[] res = new int[s.Length + 1];
res[0] = res[1] = 1;
for (int i = 2; i <= s.Length; i++)
{
if (s[i-1]=='0')
{
if (s[i - 2] == '1'|| s[i - 2] == '2')
{
res[i] = res[i - 2];
}
else
{
return 0;
}
}
else
{
res[i] = res[i - 1];
if (s[i-2]!='0')
{
int val = (s[i - 2] - '0') * 10 + s[i - 1] - '0';
if (0 < val && val < 27)
res[i] += res[i - 2];
}
}
}
return res[s.Length];
}
DP方法改进,将res数组替换成三个int就够了
再改进,倒序
public int NumDecodings(string s)
{
int n = s.Length;
if (n == 0) return 0;
int[] res = new int[n + 1];
res[n] = 1;
res[n - 1] = s[n - 1] == '0' ? 0 : 1;
for (int i = n - 2; i >= 0; i--)
if (s[i] != '0')
res[i] = (Convert.ToInt16((s.Substring(i,2))) < 27) ? res[i + 1] + res[i + 2] : res[i + 1];
return res[0];
}