Leetcode 639.解码方法2

解码方法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. 输入的字符串长度范围是 [1, 105]。
  2. 输入的字符串只会包含字符 '*' 和 数字'0' - '9'。

Leetcode 639.解码方法2

 

Leetcode 639.解码方法2

Leetcode 639.解码方法2

Leetcode 639.解码方法2

Leetcode 639.解码方法2

Leetcode 639.解码方法2

Leetcode 639.解码方法2

 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 }

 

Leetcode 639.解码方法2

 

Leetcode 639.解码方法2

 

第一步

Leetcode 639.解码方法2

第二步

Leetcode 639.解码方法2

第三步

Leetcode 639.解码方法2

第四步

Leetcode 639.解码方法2

第五步

Leetcode 639.解码方法2

第六步

Leetcode 639.解码方法2

第七步

Leetcode 639.解码方法2

第八步

Leetcode 639.解码方法2

 

 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 }

 

Leetcode 639.解码方法2

上一篇:LeetCode: 241. Different Ways to Add Parentheses


下一篇:Codeforces - 466C - Number of Ways - 组合数学