动态规划hard--639. Decode Ways II

来源:互联网 发布:lol淘宝cdk是真的吗 编辑:程序博客网 时间:2024/06/05 19:48

题目


A message containing letters from A-Z is being encoded to numbers using the following mapping way:'A' -> 1'B' -> 2...'Z' -> 26Beyond 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: 9Explanation: 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 = 18Note:The length of the input string will fit in range [1, 105].The input string will only contain the character '*' and digits '0' - '9'.

类似于上篇博客 , 编码方式没有变,但是多了一个’‘,’‘可以解码成’0’-‘9’中的任何一个 现在题目问 给你一个字符串 , 能有多少种不同的解码方式。

先来定义状态dp[i]仍然代表[0-i]有多少种不同的编码方式

接着定义初时状态

dp[0] = 9(如果s[0]==‘*’)
dp[0] = 1(如果’1’ -‘9’)
dp[0] = 0(如果’0’)

接着分析dp[1]
legal_num(这个函数用来判断合法的个数)
dp[1] =(如果s[1] == ‘0’ )和前一位组合合法的个数

dp[1] =(如果s[1] 是’1’ - ‘9’ )dp[0] + 和前一位组合合法的个数

dp[1]= (如果s[1] 是’*’) 9*dp[0] + 和前一位组合合法的个数

最后我们来写动态转移方程

dp[i] = legal_num * dp[i-2] (s[i] == ‘0’ )

dp[i] = dp[i-1] + legal_num*dp[i-2] ( s[i] ‘1’-‘9’)

dp[i] = 9*dp[i-1] + legal_num * dp[i-2] (s[i] ==’*’)

最后模上1000000007就可以ac


class Solution {public:    bool islegal( int num){        return ( num>=1 && num <=26 ) ;    }    int legal_num ( char a , char b ){        if( a >= '1' && a<='9' ){            int num = 0 ;            num = num * 10 + a - '0' ;            if( b >='0' && b<='9' ){                num = num *10 + b-'0';                if( islegal( num ) ) { return 1 ;}                else { return 0 ;}            }            else {                num *= 10 ;                int ans = 0 ;                for( int i=1 ; i<=9 ; i++){                    if( islegal( num + i ) ){ ans ++ ; }                }                return ans ;            }        }        else if( a == '*' ){            if( b>='0' && b<='9' ){                int num = 10 ;                int ans = 0 ;                for( int i=1 ; i<= 2 ; i++){                    if( islegal( num*i + b -'0' ) ){ ans ++ ;}                }                return ans ;            }            else {                int num = 10 ;                int ans =0 ;                for( int i=1;i<=2;i++){                    for( int j=1; j<=9 ;j++){                        if( islegal( num*i + j ) ){ ans ++ ;}                    }                }                return ans ;            }        }        return 0 ;    }    int numDecodings(string s) {        if( s.size() == 0 ){ return 0 ; }        long long dp[ s.size() ];        memset( dp , 0 , sizeof( dp ) ) ;        if( s[0] =='0' ){ dp[0] = 0  ;}        else if( s[0] == '*' ){ dp[0] = 9 ;}        else{ dp[0] = 1 ;}        if( s.size() == 1 ){ return dp[0] ; }        if( s[1] == '0' ){            dp[1] = legal_num( s[0] ,s[1] ) ;        }        else if( s[1] == '*' ){            dp[1] = dp[0] * 9 + legal_num(s[0] , s[1] ) ;        }        else{            dp[1] = dp[0] + legal_num( s[0] , s[1] );        }        for( int i=2 ; i<s.size() ; i++){            if( s[i] == '0' ){                dp[i] = dp[i-2] * legal_num( s[i-1] , s[i] ) % 1000000007;            }            else if( s[i] =='*' ){                dp[i] = (dp[i-2] * legal_num( s[i-1] , s[i] ) + dp[i-1] * 9 ) % 1000000007;            }            else{                dp[i] = (dp[i-2] * legal_num( s[i-1] , s[i] ) + dp[i-1]  ) % 1000000007;            }        }        return dp[s.size()-1];    }};