[LeetCode] Decode Ways [33]

题目

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.

原题链接(点我)

解题思路及代码

解码方法数量问题。英文26个字母对应1到26,给一串数字,问翻译为字母有多少种方法?
这个题第一思路是想到使用组合排列的方法,穷举所有的可能。很好,写出如下代码

class Solution {
public:
    int numDecodings(string s) {
        int count = 0;
        helper(0, s, count);
        return count;
    }
    
    void helper(int start, const string& s, int& count){
        if(start == s.size()){
            ++count;
            return;
        }
        int key=0;
        for(int i=start; i<s.size(); ++i){
            if(s[start] == '0') return;
            key = 10*key + s[i] - '0' ;
            if(key>26) return;
            helper(i+1, s, count);
        }
    }
};
但是提交后出来的结果是超时。

再想想,使用动态规划的方法来做。

对于串s[0...i]的解码数量应该和s[0...i-1], s[0...i-2]的解码数量有关系。
dp[i]: 代表s[0...i-1]的解码数量,
dp[i] = { (s[i-1]!='0')?dp[i-1]:0 } + { s[i-2...i-1]<='26' ? dp[i-2] : 0 } ;
代码如下:

class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        if( n<=0 || s[0]=='0') return 0;
        vector<int> dp(n+1, 0);
        dp[1] = dp[0] = 1;
        for(int i=2; i<=n; ++i){
            if(s[i-1] != '0') dp[i] = dp[i-1];
            if(s[i-2]=='1' || (s[i-2]=='2'&&s[i-1]<'7'))
                dp[i] += dp[i-2];
        }        
        return dp[n];
    }

};

上述动态规划优化后可以只使用3个变量而不是一个数组,代码如下:

class Solution {
public:
    int numDecodings(string s) {
        if(s.size()<=0 || s[0]=='0') return 0;
        int cur=0, cur_1 = 1, cur_2 = 1;
        for(int i=2; i<=s.size(); ++i){
            if(s[i-1] != '0') cur += cur_1;
            if(s[i-2]=='1' || (s[i-2]=='2'&&s[i-1]<'7'))
                cur += cur_2;
            cur_2 = cur_1, cur_1 = cur, cur = 0;
        }
        return cur_1;
    }
};

如果你觉得本篇对你有收获,请帮顶。

另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你可以搜索公众号: swalge  或者扫描下方二维码关注我

(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/30231807 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值