LeetCode 639. Decode Ways II

原题链接在这里:https://leetcode.com/problems/decode-ways-ii/description/

题目:

A message containing letters from A-Z is being encoded to numbers using the following mapping way:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers from 1 to 9.

Given the encoded message containing digits and the character '*', return the total number of ways to decode it.

Also, since the answer may be very large, you should return the output mod 109 + 7.

Example 1:

Input: "*"
Output: 9
Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I".

Example 2:

Input: "1*"
Output: 9 + 9 = 18

Note:

  1. The length of the input string will fit in range [1, 105].
  2. The input string will only contain the character '*' and digits '0' - '9'.

题解:

类似Decode Ways. 也是DP问题. s中含有可表示1~9的*.

若当前是 * , 自己成数有1~9共9种方式. 和前面的char成数看前面char若是'1', 有11~19 共9种方式. 若前面是'2', 有21~26共6种方式. 若前面是*, 共15种方式.

若当前不是*, 自己成数但注意当前是不是'0'. 和前面成数看前面char是不是*. 如果是'*', 当前char又小于等于'6'的话, 需要加上first*2. 以当前char为'5'为例, 有15, 25两种decode方法.

Time Complexity: O(s.length()). Space: O(s.length()).

AC Java:

 1 class Solution {
 2     int M = 1000000007;
 3     public int numDecodings(String s) {
 4         if(s == null || s.length() == 0){
 5             return 0;
 6         }
 7         
 8         long [] dp = new long[s.length()+1];
 9         dp[0] = 1;
10         dp[1] = s.charAt(0) == '0' ? 0 : s.charAt(0) == '*' ? 9 : 1;
11         for(int i = 1; i<s.length(); i++){
12             char cur = s.charAt(i);
13             char pre = s.charAt(i-1);
14             if(cur == '*'){
15                 // *单独成数
16                 dp[i+1] = 9*dp[i]%M;
17                 
18                 // *和前一位共同成数
19                 if(pre == '1'){
20                     dp[i+1] = (dp[i+1]+9*dp[i-1])%M;
21                 }else if(pre == '2'){
22                     dp[i+1] = (dp[i+1]+6*dp[i-1])%M;
23                 }else if(pre == '*'){
24                     dp[i+1] = (dp[i+1]+15*dp[i-1])%M;
25                 }
26             }else{
27                 dp[i+1] = cur == '0' ? 0 : dp[i];
28                 if(pre == '1'){
29                     dp[i+1] = (dp[i+1]+dp[i-1])%M;
30                 }else if(pre == '2' && cur <= '6'){
31                     dp[i+1] = (dp[i+1]+dp[i-1])%M;
32                 }else if(pre == '*'){
33                     dp[i+1] = (dp[i+1]+ (cur<='6' ? 2 : 1) *dp[i-1])%M;
34                 }
35             }
36         }
37         return (int)dp[dp.length-1];
38     }
39 }

更新dp[i+1]时只用到了前两个数. 可以用两个变量代替dp array.

Time Complexity: O(s.length()). Space: O(1).

AC Java:

 1 class Solution {
 2     int M = 1000000007;
 3     public int numDecodings(String s) {
 4         if(s == null || s.length() == 0){
 5             return 0;
 6         }
 7         
 8         long first = 1;
 9         long second = s.charAt(0) == '0' ? 0 : s.charAt(0) == '*' ? 9 : 1;
10         for(int i = 1; i<s.length(); i++){
11             long third = 0;
12             char cur = s.charAt(i);
13             char pre = s.charAt(i-1);
14             if(cur == '*'){
15                 // *单独成数
16                 third = 9*second%M;
17                 
18                 // *和前一位共同成数
19                 if(pre == '1'){
20                     third = (third+9*first)%M;
21                 }else if(pre == '2'){
22                     third = (third+6*first)%M;
23                 }else if(pre == '*'){
24                     third = (third+15*first)%M;
25                 }
26             }else{
27                 third = cur == '0' ? 0 : second;
28                 if(pre == '1'){
29                     third = (third+first)%M;
30                 }else if(pre == '2' && cur <= '6'){
31                     third = (third+first)%M;
32                 }else if(pre == '*'){
33                     third = (third+ (cur<='6' ? 2 : 1) *first)%M;
34                 }
35             }
36             first = second;
37             second = third;
38         }
39         return (int)second;
40     }
41 }

 

posted @ 2017-10-19 14:52  Dylan_Java_NYC  阅读(398)  评论(0编辑  收藏  举报