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