解码方法

解码方法

这道题目我考虑到了使用动态规划,但是考虑的不全面。

算法分析

分析:
  • 本题利用动态规划解决,但是需要注意分情况讨论
    • dp[i] 为str[0……i]的译码方法总数
    • 分情况讨论:
      • (极端情况)若s[i] = '0',那么若s[i-1] = '1' or '2',则dp[i] = dp[i-1];否则return 0

        解释 10合并译码,20合并译码。【30、40等无法译码】

      • 若s[i-1] = 1,则dp[i] = dp[i-1] + dp[i-2]

        解释 因为译码最多是两两结合,我们合理往前推测两位。这种情况下有两种子情况。

        1. i-2 和 i-1 合并译码 dp[i-1]中方案 2. i-1 和 i合并译码,有dp[i-2]中方案。合计dp[i-1] + dp[i-2]中方案
      • 若s[i-1] = 2 且 s[i]>'0'&&s[i] < '7',则dp同上

        解释同上

      • 其它情况不新增解码方法数
        注意:具体写代码的时候要注意边界情况。
class Solution {
public:
    int numDecodings(string s) {
        //首先排除特殊情况
        int len = s.size();
        if(s[0] == '0'){
            return 0;
        }
        int num[len];
        num[0] = 1;//初始化
        for(int i=1;i<len;i++){
            if(s[i] == '0'){//首先判断特殊条件
                if(s[i-1] == '1' || s[i-1] == '2'){
                    num[i] = i==1?num[i-1]:num[i-2];//10(20),合并译码,不增加新的译码方法
                }else{
                    return 0;//此时无法译码……3/0/5  0……
                }
            }else{
                if(s[i-1] == '1'){
                    num[i] = i==1?num[i-1]+1:num[i-1] + num[i-2];
                }else if(s[i-1] == '2' && s[i]>'0'&&s[i] < '7'){
                    num[i] = i==1?num[i-1]+1:num[i-1] + num[i-2];
                }else{
                    num[i] = num[i-1];  //其余所有情况都是不新增解码方法
                }
            }
            
        }
        return num[len-1];
    }
};

因为num[i] 仅仅可能与前两项有关,所以可以用单变量代替num[]数组,滚动变量。

class Solution {
public:
    int numDecodings(string s) {
        //首先排除特殊情况
        int len = s.size();
        if(s[0] == '0'){
            return 0;
        }
        int pre,cur;
        pre = cur = 1;
        int temp;
        for(int i=1;i<len;i++){
            temp = cur;
            if(s[i] == '0'){//首先判断特殊条件
                if(s[i-1] == '1' || s[i-1] == '2'){
                    cur = pre;//10(20),合并译码,不增加新的译码方法
                }else{
                    return 0;//此时无法译码……3/0/5  0……
                }
            }else{
                if(s[i-1] == '1' || s[i-1] == '2' && s[i]>'0'&&s[i] < '7'){
                    cur = cur + pre;
                }
            }
            pre = temp; //滚动临时变量
            
        }
        return cur;
    }
};
posted @ 2021-03-01 11:24  focusDing  阅读(148)  评论(0编辑  收藏  举报