639. 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'.

Solution

DP, time O(n), space O(n)

这道题跟"Decode Ways"的思路是一样的唯一需要注意两点:

  • 枚举1位、2位数字的时候要考虑*;
  • 注意overflow,注意如果ways[]是int,用加法得到中间结果时可能会出现负值,负数 % 正数 = 负数!所以ways[]用long来存储可以避免此问题。
class Solution {
    public int numDecodings(String s) {
        int n = s.length();
        long[] ways = new long[n + 1];  // use long to avoid overflow
        ways[0] = 1;
        final int MOD = 1000000007;
        
        for (int i = 1; i <= n; ++i) {
            ways[i] = (getWays(s.charAt(i - 1)) * ways[i - 1]) % MOD;
            if (i > 1) {
                ways[i] = (ways[i] + getWays(s.charAt(i - 2), s.charAt(i - 1)) * ways[i - 2]) 
                          % MOD;
            }
        }

        return (int) ways[n];
    }
    
    public int getWays(char c) {
        if (c == '*') {
            return 9;
        } else if (c == '0') {
            return 0;
        } else {
            return 1;
        }
    }
    
    public int getWays(char c1, char c2) {
        if (c1 != '*' && c2 != '*') {
            int val = Integer.parseInt("" + c1 + c2);
            return val >= 10 && val <= 26 ? 1 : 0;
        } else if (c1 == '*' && c2 == '*') {
            return 15;
        } else if (c2 == '*') {
            if (c1 == '1') {
                return 9;
            } else if (c1 == '2') {
                return 6;
            } else {
                return 0;
            }
        } else {
            int val = Integer.parseInt("" + c2);
            return val <= 6 ? 2 : 1;
        }
    }
}

DP, time O(n), space O(1)

可以看出,dp[i] = x * dp[i - 1] + y * dp[i - 2],可以用两个变量保存中间值,省略掉dp[]。

class Solution {
    public int numDecodings(String s) {
        int n = s.length();
        final int MOD = 1000000007;
        long[] res = new long[2];
        res[1] = 1;
        
        for (int i = 1; i <= n; ++i) {
            long curr = (getWays(s.charAt(i - 1)) * res[1]) % MOD;
            if (i > 1) {
                curr = (curr + getWays(s.charAt(i - 2), s.charAt(i - 1)) * res[0]) % MOD;
            }
            
            res[0] = res[1];
            res[1] = curr;
        }

        return (int) res[1];
    }
    
    public int getWays(char c) {
        if (c == '*') {
            return 9;
        } else if (c == '0') {
            return 0;
        } else {
            return 1;
        }
    }
    
    public int getWays(char c1, char c2) {
        if (c1 != '*' && c2 != '*') {
            int val = Integer.parseInt("" + c1 + c2);
            return val >= 10 && val <= 26 ? 1 : 0;
        } else if (c1 == '*' && c2 == '*') {
            return 15;
        } else if (c2 == '*') {
            if (c1 == '1') {
                return 9;
            } else if (c1 == '2') {
                return 6;
            } else {
                return 0;
            }
        } else {
            int val = Integer.parseInt("" + c2);
            return val <= 6 ? 2 : 1;
        }
    }
}

你可能感兴趣的:(639. Decode Ways II)