此题是和91.Decode-Ways类似的DP做法,但分情况讨论的类别更加复杂。因为dp[i]只与dp[i-1]、dp[i-2]有关,所以我们分别用k,k1,k2三个状态变量表示。
如果 s[i]=='0',此时第i位不能单独译码,必须考虑和i-1位组成的双位译码。下面分类讨论s[i-1]的各种情况。
if (s[i-1]=='*') // 末两位只能是 10, 20
k=k2*2;
else if (s[i-1]=='1' || s[i-1]=='2') // 末两位可以构成10或20
k=k2;
else
return 0;
如果 s[i]=='1'~‘6’,可以单位译码,也可以双位译码。
k=k1; // 单位译码
if (s[i-1]=='*') // 双位译码的话*只能是1,2;
k+=k2*2;
else
{
int num=stoi(s.substr(i-1,2));
if (num>=11 && num<=26) // 末两位可以译码的条件
k+=k2;
}
如果 s[i]=='7'~‘9’,可以单位译码,也可以双位译码。双位译码时,需要分别考虑 s[i-1]是*,和其他数字。基本情况同上,只不过s[i-1]=='*'时,*只能是1才可以让末两位译码。
k=k1; // 单位译码
if (s[i-1]=='*') // 双位译码的话*只能是1;
k+=k2;
else
{
int num=stoi(s.substr(i-1,2));
if (num>=11 && num<=26) // 末两位可以译码的条件
k+=k2;
}
如果 s[i]=='*',可以单位译码,也可以双位译码。双位译码时,需要分别考虑 s[i-1]是 *,0,1,2,和其他数字。注意所有涉及*的组合,必须用乘法。
k=k1*9; // 单位译码,有9种字母可能
if (s[i-1]=='*') // 末两位译码时,**只能代表11~19,21~26共15个可能。
k+=k2*15;
else if (s[i-1]=='0') // 不可能构成双位译码
pass;
else if (s[i-1]=='1') // 对应11~19
k+=k2*9;
else if (s[i-1]=='2') // 对应21~26
k+=k2*6;