zoukankan      html  css  js  c++  java
  • leetcode[90] Decode Ways

    题目:如下对应关系

    'A' -> 1

    'B' -> 2

    ...

    ‘Z’ -> 26

    现在给定一个字符串,返回有多少种解码可能。例如:Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12).

    思路:动态规划。

    dp[i]表示s[0,...,i-1]的种数。

    那么dp[i]和dp[i-1]存在什么关系呢。

    我们设singleVal为dp[i-1]所有可能组合的最后一个数字,且该数字小于10,singleCnt为dp[i-1]的最后一个数字为小于10的种数。

    例如对于“1323”的组合为:

    1,3,2,3

    13,2,3

    1,3,23

    13,23

    这是singleVal为3,singleCnt为2,如果再加入一个4,只要在前面的基础上加一个逗号,再加加入的值

    1,3,2,3,4

    13,2,3,4

    1,3,23,4

    13,23,4

    再考虑之前单一的数字和加入的数字是否可能组合,因为单一的val是3,加入的是4,组合后34是不合法的。所以此时dp[i] = dp[i-1].

    如果我们上面说的单一的数和加入的数的组合是合法的话,dp[i] = dp[i-1] + singleCnt; 再更新singleCnt为dp[i-1], singleVal为新加入的值。

    主体部分就确定了。

    那么如果当前加入的数字为0,只有当singleCnt大于零,且singleVal<=2才可能有10和20的组合可能,否则就直接返回0.

    class Solution {
    public:
    int numDecodings(string s)
    {
        int len = s.size();
        if (len == 0 || s[0] == '0') return 0;
        int singleVal = s[0] - '0';
        int singleCnt = 1;
        vector<int> dp(len);
        dp[0] = 1;
    
        for (int i = 1; i < len; ++i)
        {
            if (s[i] == '0')
            {
                if (singleCnt != 0 && singleVal <= 2)
                {
                    dp[i] = singleCnt; 
                    singleCnt = 0;
                    singleVal = 0;
                    continue;
                }
                else 
                    return 0;
            }
            if (singleVal == 1 || singleVal == 2 && s[i] <= '6')
            {
                dp[i] = dp[i - 1] + singleCnt;
                singleCnt = dp[i - 1];
                singleVal = s[i] - '0';
            }
            else
            {
                dp[i] = dp[i - 1];hh
                singleCnt = dp[i - 1];
                singleVal = s[i] - '0';
            }
        }
        return dp[len - 1];
    }
    };

    如上是我的做法,我还看了别人的做法:

    • 初始条件:dp[0] = 1, dp[1] = (s[0] == '0') ? 0 : 1
    • dp[i] = ( s[i-1] == 0 ? 0 : dp[i-1] ) + ( s[i-2,i-1]可以表示字母 ? dp[i-2] : 0 ), 其中第一个分量是把s[0...i-1]末尾一个数字当做一个字母来考虑,第二个分量是把s[0...i-1]末尾两个数字当做一个字母来考虑

    代码如下:

    class Solution {
    public:
        int numDecodings(string s) {
            // IMPORTANT: Please reset any member data you declared, as
            // the same Solution instance will be reused for each test case.
            //注意处理字符串中字符为0的情况
            int len = s.size();
            if(len == 0)return 0;
            int dp[len+1];//dp[i]表示s[0...i-1]的解码方法数目
            dp[0] = 1;
            if(s[0] != '0')dp[1] = 1;
            else dp[1] = 0;
            for(int i = 2; i <= len; i++)
            {
                if(s[i-1] != '0')
                    dp[i] = dp[i-1];
                else dp[i] = 0;
                if(s[i-2] == '1' || (s[i-2] == '2' && s[i-1] <= '6'))
                    dp[i] += dp[i-2];
            }
            return dp[len];
        }
    };
  • 相关阅读:
    用户管理的设计--3.jquery的ajax实现二级联动
    用户管理的设计--2.新增用户信息实现
    用户管理的设计--1.首页查询功能实现
    使用ajax实现简单的带百分比进度条
    python && java
    es6 modules 和commonjs
    es6 promise
    CSS“隐藏”元素的几种方法的对比
    jquery extend
    html5自定义属性
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4115926.html
Copyright © 2011-2022 走看看