返回顶部

91. 解码方法

一条包含字母 A-Z 的消息通过以下方式进行了编码:

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

给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例 1:

输入: "12"
输出: 2
解释: 它可以解码为 "AB"1 2)或者 "L"12)。

示例 2:

输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

思路:DP问题,当前位置(个位)与前一个位置(十位)上的两个数字刚好组成两位数,这两位数决定了递推方程:

代码:

 1 class Solution {
 2 public:
 3     int numDecodings(string s) {
 4         //F(m) = F(m-1) + F(m-2)
 5         int length = s.length();
 6         if(length == 0) return length;
 7         if(length == 1) {
 8             if(s[0] == '0') return 0;
 9             else return 1;
10         } 
11         int m = 1,n = 2;
12         int num = (s[1] -'0' + 0)+ (s[0] -'0' + 0) * 10;
13         if(num < 10 || (num % 10 == 0 && num / 10 > 2)) {
14                 return 0;
15             } else if (num == 10 || num == 20 || num > 26) {
16                 n = 1;
17             }
18         if((s[0] == '1' || (s[0] == '2' && (s[1] -'0' + 0) < 7)) && s[1] != '0') n = 2;
19         for(int i = 2 ;i < length ;++i) {
20             int num = (s[i] -'0' + 0)+ (s[i - 1] -'0' + 0) * 10;
21             if(num == 0 || (num % 10 == 0 && num / 10 > 2)) {
22                 return 0;
23             } else if (num < 10 || num > 26) {
24                 m = n;
25             }
26             else if((10 < num && num < 20) || (20 < num && num <= 26)) {
27                 n = m + n;
28                 m = n - m;
29             } else if(num == 10 || num == 20){
30                 n = m + n;
31                 m = n - m;
32                 n = n - m;
33             }
34         }
35         return n;
36     }
37 };

后记:动态规划的解法,时间复杂度O(n),空间复杂度O(1),感觉这两点都没啥可优化的了。但是感觉代码写的有点丑,可以整合下。

精简后的代码:

 1 class Solution {
 2 public:
 3     int numDecodings(string s) {
 4         if(s[0] == '0') return 0;
 5         int pre = 1,cur = 1;
 6         int length = s.length();
 7         for(int i = 1;i < length ;++i) {
 8             int temp = cur;
 9             if(s[i] == '0') {
10                 if(s[i - 1] == '2' || s[i - 1] == '1') cur = pre;
11                 else return 0;
12             } else if(s[i - 1] == '1' || (s[i-1] == '2' && s[i] < '7' && s[i] > '0')) {
13                 cur = pre + cur;
14             }
15             pre = temp;
16         }
17         return cur;
18     }
19 };
在此感谢作者:pris_bupt
链接:https://leetcode-cn.com/problems/decode-ways/solution/c-wo-ren-wei-hen-jian-dan-zhi-guan-de-jie-fa-by-pr/
posted @ 2020-04-11 16:36  Swetchine  阅读(179)  评论(0编辑  收藏  举报