Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
2018-02-19 19:05
260 查看
Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
题目描述
一条报文包含字母A-Z,使用下面的字母-数字映射进行解码
'A' -> 1 'B' -> 2 ... 'Z' -> 26
给一串包含数字的加密报文,求有多少种解码方式
举个例子,已知报文
"12",它可以解码为
AB(1 2),也可以是
L (12)
所以解码方式有2种。
测试样例
Input: "0" "121212" "101010" "1001" "0101" Output: 0 13 1 0 0
详细分析
这道题不难,不过corner cases比较多,需要仔细分析。先考虑1212这个例子:(为了表达方便,我们用逗号分隔表示每种解码方式而不用扳手指算,比如1212的一种解码方式为
12,12而不用
L,L)
1=>
1
12=>
1,2 12
121=>
1,2,1 1,21 12,1
1212=>
1,2,1,2
1,21,2 12,1,2
1,2,12
12,12
到这里就可以总结出规律了,对于
1212,其实是两种解码的和:
1,2,1,(2) 1,21,(2) 12,1,(2) ----------- 1,2,(12) 12,(12)
分割线上面是
121的解码方式,并在后加以当前下标的2,分割线下面是
12的解码方式加以当前下标和前一个下标表示的字符。
可以看出,如果当前字符和前面一个字符可以构成
>10 && <=26(不包括20,至于为什么等下说)的字符,那么当前解码方式就是:
dp[i]=dp[i-1]+dp[i-2]
现在考虑一些corner case,如果当前字符是
0,那么它并不符合上面的递推公式,考虑
2020:
20=>
20
202=>
20,2
2020=>
20,(20)
可以看到
2020,由于0不在解码范围内,所以它不能与前一项通过添加后缀的方式构成解码方式,它只是简单等于前两项然后加上后缀20,同理还有10。
按照这种思路,我们可以得出下面的状态转移:
let x = s.substr(i-1,2); x>0 && x<10: dp[i]=dp[i-1] x==10: dp[i]=dp[i-2] x>10&&x<20: dp[i]=dp[i-1]+dp[i-2] x==20: dp[i]=dp[i-2] x>20&&x<=26: dp[i]=dp[i-1]+dp[i-2] x>26&&x%10!=0: dp[i]=dp[i-1]; x>26&&x%10==0: return 0
代码实现
代码太烂凑合看吧...class Solution { public: int numDecodings(string s) { if(s.length()==0){ return 0; } if(s[0]=='0'){ return 0; } if(s.length()==1){ return 1; } int dp[100000]; dp[0]=1; std::string ns = s.substr(0,2); int t = atoi(ns.c_str()); if(t>0 && t<10){ return 0; }else if(t==10){ dp[1]=1; }else if(t>10 && t<20){ dp[1]=2; }else if(t==20){ dp[1]=1; }else if(t>20 && t<=26){ dp[1]=2; }else if(t>26 && t%10!=0){ dp[1]=1; }else{ return 0; } if(s.length()==2){ return dp[1]; } for(int i=2;i<s.length();i++){ std::string tempStr = s.substr(i-1,2); int n = atoi(tempStr.c_str()); if((n>26 && n%10!=0)||(n>0 && n<10)){ dp[i]=dp[i-1]; }else if(n>10 && n<=26&& n!=20){ dp[i]=dp[i-1]+dp[i-2]; }else if(n==10 || n==20){ dp[i]=dp[i-2]; }else if(n==0 || n%10==0){ return 0; } } return dp[s.length()-1]; } };
相关文章推荐
- Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
- (Java) LeetCode 91. Decode Ways —— 解码方法
- LeetCode 91. Decode Ways(解码方法)
- [LeetCode] 91. Decode Ways 解码方法
- LeetCode 91. Decode Ways(解码方法)
- PHP处理Json字符串解码返回NULL的解决方法
- leetCode 91.Decode Ways (解码方式) 解题思路和方法
- [LeetCode] Decode Ways II 解码方法之二
- [LeetCode] Decode Ways 解码方法个数、动态规划
- [LeetCode] 639. Decode Ways II 解码方法 II
- PHP处理Json字符串解码返回NULL的解决方法
- leetcode_解码方法(动态规划)
- leetcode 639. Decode Ways II 解码方法+动态规划DP+无论如何也不会做
- Leetcode-91. Decode Ways
- 化解字符串不能超过8000的方法及交叉表的处理
- c++ 中文字符串处理方法
- 【Leetcode】91. Decode Ways
- shell脚本处理字符串常用方法
- LeetCode 91. Decode Ways
- [LeetCode] 91. Decode Ways