动态规划中级教程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.

题目大意: 给我们一个字符串只包含数字0-9,告诉我们’a’-‘z’对应数字的’1’-“26”
问我们一共可以得到多少不同的解码方式

问题是多少种不同,很容易想到动态规划

先定义动态规划状态 dp[i]代表[0,i]可以组成多少种不同的编码方式

接着定义初时状态
dp[0] = 1 (‘1’-‘9’)
dp[0] = 0 (‘0’)
上面的初时状态代表 ‘1’-‘9’那么一种否则0种

接着我们填写dp[1]
如果[0,1]构成的两个字符大小在(10-26)之间代表本身是一种解码方式
dp[1]++;

如果[1]是合法的那么
dp[1] = 1+dp[0];

接着我们可以分析后面的状态并且写出状态转移方程

dp[i] = (如果本身着一位可以编码并且和前一位的和可以编码)dp[i-1]+dp[i-2].

dp[i] = ( 如果本身可以编码但是前一位不可以编码) dp[i-1].

dp[i] = (如果本身不可以编码但是前一位和可以编码) dp[i-2].

状态转移写完后可以写出相应的程序如下


class Solution {
public:
    bool islegal( string s ){
        int num = 0 ;
        for( int i=0 ; i<s.size() ; i++){
            num = num * 10 + s[i] -'0';
        }
        if( num >=10 && num <= 26) { return true ;}
        return false;
    }

    int numDecodings(string s) {
        if( s.size() == 0 ){ return 0 ;} 
        if( s.size() == 1 ){ return (s[0]!='0') ; }
        int dp[s.size()];
        memset( dp , 0 , sizeof( dp ) ) ;
        if(s[0]!='0' ){ dp[0] = 1 ; }
        else{ dp[0] = 0 ; }
        if( islegal( s.substr( 0 , 2 ) ) ) {
            if( s[1] =='0'){ dp[1] = 1 ; }
            else{ dp[1] = 2; }
        }
        else{
            if( s[1] == '0' ){ dp[1] = 0 ; }
            else { dp[1] = dp[0] ;}
        }
        for( int i = 2 ; i< s.size() ; i++ ){
            if( s[i] != '0' ){
                if( islegal( s.substr( i-1 , 2 ) ) ){
                    dp[i] = dp[i-1] + dp[i-2];
                }
                else{
                    dp[i] = dp[i-1] ;
                }
            }
            else{
                if( islegal( s.substr( i-1 , 2 ) ) ){
                    dp[i] = dp[i-2];
                }
                else{
                    dp[i] = 0 ;
                }
            }
        }
        return dp[s.size()-1] ;
    }
};

时间复杂度分析

O(n)

空间复杂度分析

O(n)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值