• [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 )

  • 相关阅读:
    2:(sql语言的数据类型)
    4:关系数据库标准语言sql(sql概述:功能,特点)
    毕业设计:反射,枚举
    毕业设计:阶段性总结
    3.9易错题
    3.8(关系代数表达查询)
    3.7(附加的关系运算)
    3.5(关系的完整性约束)、(关系代数的五种基本运算:选择和投影(关于行运算和列运算的概念还不清晰))
    3.4(从E-r概念模型到关系模型即DBMS直接支持的数据模型)
    php 如何获取图片后缀和可变函数的使用实战
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5111954.html
Copyright © 2020-2023  润新知