91. Decode Ways

Problem:

A message containing letters from A-Z is being encoded to numbers using the following mapping:

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

Given a non-empty string containing only digits, determine the total number of ways to decode it.

Example 1:

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

Example 2:

Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

思路:

用DP算法。设数组size为n,初始化dp[n+1]数组,其中dp[i]表示到第i个字符所有的解码总数,最后返回dp[n]即可。注意第i个字符对应的数组下标为i-1。分以下几种情况讨论:

  1. 如果当前位置为0,前一位置为0或大于2,则无法解码;
  2. 如果当前位置为0,前一位置值为1或2,则dp[i] = dp[i-2];
  3. 如果当前位置不为0,前一位置为0,则dp[i] = dp[i-1];
  4. 如果当前位置与前一位置都不为0,且组成的2位数大于26,则dp[i] = dp[i-1];
  5. 如果当前位置与前一位置都不为0,且组成的2位数不大于26,则可以单独解码与合并起来解码,则dp[i] = dp[i-1] + dp[i-2]。

Solution:

int numDecodings(string s) {
    if (s.empty() || s[0] - '0' == 0)   return 0;

    int n = s.size();
    vector<int> dp(n+1);
    //赋初值
    dp[0] = 1;    //表示字符串为空情况,与上面的有区别,额外初始化
    dp[1] = 1;    //表示字符串只含有1个字符的情况

    for (int i = 2; i < n + 1; i++) {
        int cur = s[i-1] - '0';
        int prev = s[i-2] - '0';

        //if (cur == 0 && prev == 0 || cur == 0 && prev > 2)  return 0;

        //else if (cur == 0)  dp[i] = dp[i-2];

        if (cur == 0) {
            if (prev == 0 || prev > 2)  return 0;
            else dp[i] = dp[i-2];
        }

        else if (prev == 0 || prev * 10 + cur > 26)  dp[i] = dp[i-1];


        else dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[n];
}

性能:

Runtime: 4 ms  Memory Usage: 8.7 MB

相关链接如下:

知乎:littledy

欢迎关注个人微信公众号:小邓杂谈,扫描下方二维码即可

作者:littledy
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/dysjtu1995/p/12285424.html