[LeetCode] 91、解码方法

本文详细解析了一种基于数字的编码解码算法,该算法将字母A-Z转换为1-26的数字,并探讨了如何计算给定数字串的可能解码方法总数。通过动态规划方法,介绍了状态转移方程及其应用,特别强调了遍历方向的重要性。

题目描述

一条包含字母 A-Z 的消息通过以下方式进行了编码:

'A' -> 1
'B' -> 2
...
'Z' -> 26

给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例:

输入: "12"
输出: 2
解释: 它可以解码为 "AB"1 2)或者 "L"12)。

解题思路

状态转移方程: d[i] = dp[i+1] + g(i,i+1) * dp[i+2] => 可以看出需要从后往前遍历。

注:dp后还可以“空间压缩”到常数级别的空间复杂度,因为每次的 dp[i] 只与 dp[i+1]dp[i+2] 有关,因此我们可以用两个变量来记录并不断更新 dp[i+1]dp[i+2] 。此外,在做动态规划题目的时候,要特别注意“遍历方向”的问题,要保证我们的算法是“自底向上”求解的。(由小到大)

参考代码

注:本题从1开始编码,需要一些特判才行。可直接参考《剑指offer》第46题处的代码。

class Solution {
public:
    int numDecodings(string str) {
        int length = str.length();
        if(length == 0)
            return 0;
        
        vector<int> dp(length, 0);
        for(int i = length-1; i >= 0; i--){
            int temp = 0;
            if(i == length-1 && (str[i] - '0') > 0){  // 注意要求(str[i] - '0') > 0 特判
                dp[i] = 1;
                continue;
            }
            
            if(i <= length-2 && (str[i] - '0') > 0){  // 注意要求(str[i] - '0') > 0
                if((str[i] - '0') == 0)  // 若当前的位置的数字为0,这是无法有效解码的。特判
                    continue;
                temp += dp[i+1];
                int twoDigitsNum = 10 * (str[i] - '0') + (str[i+1] - '0');
                if(twoDigitsNum >= 10 && twoDigitsNum <= 26){
                    if(i == length-2)
                        temp += 1;
                    else
                        temp += dp[i+2];
                }
            }
            
            dp[i] = temp;
        }
        
        return dp[0];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值