解码方法2
一条包含字母 A-Z 的消息通过以下的方式进行了编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
除了上述的条件以外,现在加密字符串可以包含字符 '*'了,字符'*'可以被当做1到9当中的任意一个数字。
给定一条包含数字和字符'*'的加密信息,请确定解码方法的总数。
同时,由于结果值可能会相当的大,所以你应当对10 + 7取模。(翻译者标注:此处取模主要是为了防止溢出)
示例 1 :
输入: "*"
输出: 9
解释: 加密的信息可以被解密为: "A", "B", "C", "D", "E", "F", "G", "H", "I".
示例 2 :
输入: "1*"
输出: 9 + 9 = 18(翻译者标注:这里1*可以分解为1,* 或者当做1*来处理,所以结果是9+9=18)
说明 :
- 输入的字符串长度范围是 [1, 10]。
- 输入的字符串只会包含字符 '*' 和 数字'0' - '9'。
public class Solution {
int M = 1000000007;
public int numDecodings(String s) {
Integer[] memo=new Integer[s.length()];
return ways(s, s.length() - 1,memo);
}
public int ways(String s, int i,Integer[] memo) {
if (i < 0)
return 1;
if(memo[i]!=null)
return memo[i];
if (s.charAt(i) == '*') {
long res = 9 * ways(s, i - 1,memo);
if (i > 0 && s.charAt(i - 1) == '1')
res = (res + 9 * ways(s, i - 2,memo)) % M;
else if (i > 0 && s.charAt(i - 1) == '2')
res = (res + 6 * ways(s, i - 2,memo)) % M;
else if (i > 0 && s.charAt(i - 1) == '*')
res = (res + 15 * ways(s, i - 2,memo)) % M;
memo[i]=(int)res;
return memo[i];
}
long res = s.charAt(i) != '0' ? ways(s, i - 1,memo) : 0;
if (i > 0 && s.charAt(i - 1) == '1')
res = (res + ways(s, i - 2,memo)) % M;
else if (i > 0 && s.charAt(i - 1) == '2' && s.charAt(i) <= '6')
res = (res + ways(s, i - 2,memo)) % M;
else if (i > 0 && s.charAt(i - 1) == '*')
res = (res + (s.charAt(i)<='6'?2:1) * ways(s, i - 2,memo)) % M;
memo[i]= (int)res;
return memo[i];
}
}
第一步
第二步
第三步
第四步
第五步
第六步
第七步
第八步
public class Solution {
int M = 1000000007;
public int numDecodings(String s) {
long[] dp = new long[s.length() + 1];
dp[0] = 1;
dp[1] = s.charAt(0) == '*' ? 9 : s.charAt(0) == '0' ? 0 : 1;
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == '*') {
dp[i + 1] = 9 * dp[i];
if (s.charAt(i - 1) == '1')
dp[i + 1] = (dp[i + 1] + 9 * dp[i - 1]) % M;
else if (s.charAt(i - 1) == '2')
dp[i + 1] = (dp[i + 1] + 6 * dp[i - 1]) % M;
else if (s.charAt(i - 1) == '*')
dp[i + 1] = (dp[i + 1] + 15 * dp[i - 1]) % M;
} else {
dp[i + 1] = s.charAt(i) != '0' ? dp[i] : 0;
if (s.charAt(i - 1) == '1')
dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
else if (s.charAt(i - 1) == '2' && s.charAt(i) <= '6')
dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
else if (s.charAt(i - 1) == '*')
dp[i + 1] = (dp[i + 1] + (s.charAt(i) <= '6' ? 2 : 1) * dp[i - 1]) % M;
}
}
return (int) dp[s.length()];
}
}