• 91. Decode Ways


    问题:

    给定由0~9构成的编码字符串。

    编码前,

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

    按照以上方法进行编码。

    求编码前的字符串组合的可能数。

    Example 1:
    Input: s = "12"
    Output: 2
    Explanation: "12" could be decoded as "AB" (1 2) or "L" (12).
    
    Example 2:
    Input: s = "226"
    Output: 3
    Explanation: "226" could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
    
    Example 3:
    Input: s = "0"
    Output: 0
    Explanation: There is no character that is mapped to a number starting with 0.
    The only valid mappings with 0 are 'J' -> "10" and 'T' -> "20", neither of which start with 0.
    Hence, there are no valid ways to decode this since all digits need to be mapped.
    
    Example 4:
    Input: s = "06"
    Output: 0
    Explanation: "06" cannot be mapped to "F" because of the leading zero ("6" is different from "06").
     
    Constraints:
    1 <= s.length <= 100
    s contains only digits and may contain leading zero(s).
    

      

    解法:DP(动态规划)

    1.确定【状态】:

    • 字符串s的index:i

    2.确定【选择】:

    dp[i]:SUM {

    • 两个数字->一个字母
      • dp[i-2]
        • 条件:s[i-1]==2 && s[i]<=6
        • or       s[i-1]==1
    • 一个数字->一个字母
      • dp[i-1]
        • 条件:s[i]!=0
        • if s[i]==0 then return 0.
    • }

    3. dp[i]的含义:

    • 字符串s[0~i]  能够构成编码的可能数。 

    4. 状态转移:

    dp[i]= SUM {

    • if((s[i-1]==2 && s[i]<=6) || s[i-1]==1) dp[i-2]
      • others: 0
    • if(s[i]!=0) dp[i-1]
      • others: 0
    • }

    5. base case:

    • dp[1]= (s[0]!=0)? 1 : 0;
    • dp[0]=1;//如 "12"->直接编码为"H",dp[2]+=dp[0],能够加出一个1。

    代码参考:

     1 class Solution {
     2 public:
     3     //dp[i]: the number of ways to decode s[0~i]
     4     //opt: case_1+case_2
     5     //case_1: dp[i-1]
     6     //case_2: if((s[i-1]==2 && s[i]<=6) || s[i-1]==1) dp[i-2]
     7     //base:dp[0]=0  dp[1]=1
     8     int numDecodings(string s) {
     9         int pre_0=1, pre_1=1, res=pre_1;
    10         int len = s.length();
    11         if(s[0]<='0') return 0;
    12         for(int i=1; i<len; i++) {
    13             if(s[i]>'0') res = pre_1;
    14             else res = 0;
    15             //cout<<res<<endl;
    16             if((s[i-1]=='2' && s[i]<='6') || s[i-1]=='1') res += pre_0;
    17             pre_0 = pre_1;
    18             pre_1 = res;
    19         }
    20         return res;
    21     }
    22 };
  • 相关阅读:
    CListCtrl基本用法
    学习c++:获得函数私有变量
    vc 学习笔记 之工程
    怎样用c/c++编程连接mysql数据库?
    几天的总结,CEdit,CListctl.......
    c++ const成员函数
    PreparedStatement是如何大幅度提高性能的 (转)
    __declspec(dllexport)与.def文件
    让我懂得 多态性 的网友的帖子
    解读工程 之困惑之处
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14569524.html
Copyright © 2020-2023  润新知