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:
- The length of the input string will fit in range [1, 105].
- 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 }