• 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 }
  • 相关阅读:
    java 泛型详解
    Vector源码解析
    栈的应用 函数调用
    java中ArrayList 遍历方式、默认容量、扩容机制
    java代码实现自定义栈 + 时间复杂度分析
    mySql分页Iimit优化
    Mybatis 动态SQL注解 in操作符的用法
    设计模式之 外观模式
    设计模式之 装饰器模式
    设计模式之 组合模式
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/7692478.html
Copyright © 2020-2023  润新知