zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/7692478.html
Copyright © 2011-2022 走看看