问题:
给定由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-2]
- 一个数字->一个字母
- dp[i-1]
- 条件:s[i]!=0
- if s[i]==0 then return 0.
- dp[i-1]
- }
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 };