题目
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:
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];
}
};