LeetCode Decode Way Series Problems

091 decode ways:
given a number String, return the number of unique number of ways to decode that.
Input: “226”
Output: 3
Explanation: It could be decoded as “BZ” (2 26), “VF” (22 6), or “BBF” (2 2 6).

At the first glance of this problem, we know that this problem is a dp problem.
in this problem, the dp equation is dp[i] = dp[i-1] + (dp[i-2]), and dp[i-2] is optional if substring(i-2,i) is within the range of [10, 26].

based on this, the solution is pretty simple:

class Solution {
    public int numDecodings(String s) {
        if(s == null || s.length() == 0) return 0;
        
        int n = s.length();
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = s.charAt(0) == '0' ? 0 : 1;
        for(int i = 2; i <= n; i++){
            int first = Integer.valueOf(s.substring(i-1,i));
            int second = Integer.valueOf(s.substring(i-2,i));
            //deal with dp[i-1]
            if(first >= 1 && first <= 9){
                dp[i] += dp[i-1]; //why it is not dp[i] += 9 * dp[i-1]? because we are given a fixed string and every position is fixed with number
            }
            //deal with dp[i-2]
            if(second >= 10 && second <= 26){
                dp[i] += dp[i-2];
            }
        }
        return dp[n];
    }
}

LC639 decode ways2:
this problem is a follow up of decode ways1. and this time, we added a wildcard in the input String: “*”, which represents any numbers from 1 to 9.

class Solution {
    public int numDecodings(String s) {
        long[] dp = new long[s.length() + 1];
        dp[0] = 1;
        if (s.charAt(0) == '0') { //if head is 0 then the string is invalid
            return 0;
        }
        dp[1] = s.charAt(0) == '*' ? 9 : 1;
        
        for (int i = 2; i <= s.length(); i++) {
            char first = s.charAt(i-2);
            char second = s.charAt(i-1);
            
            //deal with dp[i-1]
            if (second == '*') {
                dp[i] += 9 * dp[i-1];
            } else if (second > '0') {
                dp[i] += dp[i-1];
            } //if second == '0', we didn't do anything since this can't form any valid number
            
            //deal with dp[i-2]
            if (first == '*') {
                if (second == '*') {
                    dp[i] += 15 * dp[i-2];
                } else if (second <= '6') {
                    dp[i] += 2 * dp[i-2];
                } else {
                    dp[i] += dp[i-2];
                }
            } else if (first == '1' || first == '2') {
                if (second == '*') {
                    if (first == '1') {
                        dp[i] += 9 * dp[i-2];
                    } else if (first == '2') {
                        dp[i] += 6 * dp[i-2];
                    }
                } else if (Integer.parseInt(s.substring(i-2, i)) <= 26) {
                    dp[i] += dp[i-2];
                }
            } //if first is neither * or 1 or 2, then we can't see the s.substring(i-2,i) as a number,so we do nothing
            
            dp[i] %= 1000000007;
        }
        return (int)dp[s.length()];
    }
}

this solution seems complex than the decode ways1, but there are basically the same idea.
we still divide the solution into to parts, dp[i] deal with dp[i-1] and dp[i] deal with dp[i-2].

when dp[i] deals with dp[i-1], that means we only needs to consider s.charAt(i-1), there are three senerios: s.charAt(i-1) == ‘*’ / ‘0’ / not ‘0’, and each one of them we will have a reaction.
when dp[i] deals with dp[i-2], that means we needs to consider the combination of s.charAt(i-1) and s.charAt(i-2), so:
when s.charAt(i-2) == ‘*’:
if s.charAt(i-1) == ‘
if s.charAt(i-1) <= ‘6’
if s.charAt(i-1) > ‘6’
when s.charAt(i-2) == ‘1’ || s.charAt(i-2) == ‘2’:
if s.charAt(i-1) == '

if s.charAt(i-2) == ‘1’
if s.charAt(i-2) == ‘2’
if s.charAt(substring(i-2, i) <= 26) :

when s.charAt(i-2) > 2:

posted @ 2020-05-25 02:33  EvanMeetTheWorld  阅读(16)  评论(0)    收藏  举报