Another classic DP problems.
Given a non-empty string containing only digits, determine the total number of ways to decode it.
1->A
2->B

How many ways can we decode a given string?

for problem that asked us: how many ways…, instead of print out all the ways that can decode. so that implied us to use dp

and the dp equation is:
dp[i] means the number of decode ways if we only got the first i+1 chars
dp[i] = dp[i-1] (if the i-1 th char is between 1 to 9) + dp[i-2] (if the i-2,i -1 th char is between 10 and 26)

first, based on this thought, the code implemented are as followed: but it’s overflowed

class Solution {
    public int numDecodings(String s) {
        
        if(s == null || s.length() == 0) return 0;
        
        int n = s.length();
        int[] dp = new int[n];
        
        dp[0] = s.charAt(0) == '0'?0:1;
        
        for (int i = 1; i < n; i++) {
            int oneDigit = Integer.valueOf(s.substring(i, i + 1));
            int twoDigit = Integer.valueOf(s.substring(i-1, i + 1));
            
            if (oneDigit >= 1 && oneDigit <= 9) {
                dp[i] += dp[i-1];
            }
            if (twoDigit >= 10 && twoDigit <= 26) {
                dp[i] += dp[i-2]; //when i == 1, here is out of range
            }
        }
        return dp[n-1];
    }
}

so instead of define dp[i] as the first i+1(for example: dp[0] as the decode ways of only first char), we define dp[i] as the first i chars, which actually makes it much easier to remember, and we only needs to initialize dp as the length of n+1.

but here comes the most hard to understand part: dp[0] = 1 instead of 0. but it’s right.

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; //this is the trickest part: dp[0] should be 1 instead of 0, but that's doesn;t suitable for its meaning. but we should assign dp[0] with 1 because, jus thinking about the "12", so when i = 2, dp[2] = dp[1] + dp[0], so it should be 1+1 instead of 1+0. it's actually the based case of dp[i-2]
        dp[1] = s.charAt(0) == '0'?0:1;
        
        for (int i = 2; i <= n; i++) {
            int oneDigit = Integer.valueOf(s.substring(i - 1, i));
            int twoDigit = Integer.valueOf(s.substring(i - 2, i));
            
            if (oneDigit >= 1 && oneDigit <= 9) {
                dp[i] += dp[i-1];
            }
            if (twoDigit >= 10 && twoDigit <= 26) {
                dp[i] += dp[i-2];
            }
        }
        return dp[n];
    }
}