zoukankan      html  css  js  c++  java
  • Decode Ways

    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.

    思路:DP。这题依旧可以保持O(1)的空间复杂度。

    先考虑字符串最普遍的情况,假设有字符串S1S2S3, 假设我们已经考虑到了S3,则S3有2种情况:

    1)S2S3可以组成10-26, 设dp[2]为到S3位置所有可能的情况,则dp[2] = dp[0] + dp[1]。

    先解释下这个公式为什么会成立,dp[0]为S1可能的解读情况,而当S2和S3各自单独解读为一个字母时,可能情况并没有增加,还是dp[0]。再考虑dp[1],它是截止到S2可能的解读情况,排除掉之前dp[0]时各自单独解读的情况,这里有两种可能:S1S2可以构成10-26,S3自己单独解读(可能情况数等于S1S2一起解读时的情况数),或者S2S3解读为10-26(可能情况数等于S2单独解读时的情况数),两者加起来正好是截止到S2的可能情况总数,即dp[1]。将上述情况进行综合得dp[2] = dp[0] + dp[1]。

    2)S2S3不能组合成10-26, 则相当于在截止于S2的所有可能情况后面都额外加了一个无关紧要的S3,并没有增加额外的情况,因此dp[2] = dp[1]。

    还有一点要注意的是,如果S3为0,则要么必需和S2组合到一起解读,要么整个字符串是非法的。因为单独一个0无法解读。因此,当S3为0时,dp[2] = dp[1]。而此时无法和S2组合,也就是非法的情况,我们在下面的实现方法中说明。

    实现:我们维护两个值,preslow和prefast。

    假设当前我们到了Si,则preslow为截止到Si-2时的情况数,prefast为截止到Si-1时的情况数。

    先判断当前Si是否为0,若是,则令prefast = 0。

    若Si能和Si-1构成10-26, 则领prefast = prefast + preslow;preslow = prefast - preslow。

    这里可以看到,如果当前Si为0的话,prefast为0,则prefast=prefast + preslow将为preslow,即截止到si-2时的可能情况,与我们上面讨论的结果一致。否则就是dp[i -2] + dp[i - 1]。这样计算完之后,prefast已经更新到了截止于Si的值,因此preslow也往前移一位,得到之前Si-1的值。

    如果Si不能和Si-1构成10-26,则dp[i] = dp[i-1],这里就是保持prefast值不变。而preslow仍要前移一位,值也要更新为prefast。这里要注意到,假如Si为0,则prefast当前已经为0,而在当前情况下这个字符串是非法的。经过这一步后,preslow也变成了0。所以之后不管怎么样,两个变量的值都将永远是0。

    最后,prefast的值即为结果。

     1 class Solution {
     2 public:
     3     int numDecodings(string s) {
     4         int n = s.size();
     5         if (n < 1 || s[0] == '0') return 0;
     6         int preslow = 1, prefast = 1;
     7         for (int i = 1; i < n; i++)
     8         {
     9             if (s[i] == '0') prefast = 0;
    10             if (s[i - 1] == '1' || (s[i - 1] == '2' && s[i] < '7'))
    11             {
    12                 prefast = preslow + prefast;
    13                 preslow = prefast - preslow;
    14             }
    15             else preslow = prefast;
    16         }
    17         return prefast;
    18     }
    19 };
  • 相关阅读:
    spring aop实现过程之三Spring AOP中Aspect编织的实现
    spring aop实现过程之一代理对象的生成
    数据库常用面试题(SQL Server) (转载)
    回溯法解八后问题
    masmplus增加调试工具
    c++ new关键字 详解
    EMU8086 编译器使用简介
    汇编操作显存
    回溯法简介
    汇编链接时 错误:unresolved external symbol _WinMainCRTStartup
  • 原文地址:https://www.cnblogs.com/fenshen371/p/4935312.html
Copyright © 2011-2022 走看看