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

题目


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];
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值