[leedcode 91] Decode Ways

A message containing letters from A-Z is being encoded to numbers using the following mapping:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given an encoded message containing digits, determine the total number of ways to decode it.

For example,
Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

The number of ways decoding "12" is 2.

public class Solution {
    public int numDecodings(String s) {
        /*本题类似于上台阶求次数的题型,因此需要利用DP思想保存住中间的子解,但是dp[i] 是否等于dp[i-1] + dp[i-2]需要判断字符是否满足要求
        
        
        使用递归会超时,所以使用动态规划DP的方法来做。
        对于串s[0...i]的解码数量应该和s[0...i-1], s[0...i-2]的解码数量有关系。
        dp[i]: 代表s[0...i-1]的解码数量,因此DP的长度是s长度+1,DP[0]=DP[1]=1
        dp[i] = { (s[i-1]!='0')?dp[i-1]:0 } + { s[i-2...i-1]<='26' ? dp[i-2] : 0 } ;
        
        从头到尾扫这个String,从s[0...i-1]组成的String,有多少种解码组合,那么有两种情况

        第一:如果s[i-1]所对应的的单个字符可以解码,那么dp[i](s[0...i-1])就包括前dp[i-1]位所积累的组合数 dp[i] = dp[i-1] 

        第二:如果不仅s[i-1]所对应的的单个字符可以解码,s[i-2...i-1],两个字符组成的也可以解码,那么不仅包括dp[i-1]积累的组合数,也包括dp[i         -2]位积累的组合数 dp[i] = dp[i-1] + dp[i-2]

        我们建一个n+1的数组,为了程序简洁,我们在最前面放一个1。*/
        if(s==null||s.length()<1) return 0;
        if(s.charAt(0)=='0') return 0;
        int[]dp=new int[s.length()+1];
        dp[0]=1; dp[1]=1;
        for(int i=2;i<=s.length();i++){
            if(s.charAt(i-1)!='0')dp[i]=dp[i-1];
            if(isValid(s.substring(i-2,i))) dp[i]+=dp[i-2];
        }
        return dp[s.length()];
    }
    public boolean isValid(String s){
        if(s.charAt(0)=='0') return false;
        if(s.charAt(0)=='1'||(s.charAt(0)=='2'&&s.charAt(1)<='6')) return true;
        return false;
    }
}

 

你可能感兴趣的:(decode)