Decode Ways II - LeetCode
题目:
A message containing letters from A-Z is being encoded to numbers using the following mapping way:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Beyond that, now the encoded string can also contain the character ‘*’, which can be treated as one of the numbers from 1 to 9.
Given the encoded message containing digits and the character ‘*’, return the total number of ways to decode it.
Also, since the answer may be very large, you should return the output mod 10^9 + 7.Example 1:
Input: “*”
Output: 9
Explanation: The encoded message can be decoded to the string: “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”.
特地找了一道动态规划的题目做,这道题还是比较简单的。
给出一串以'0-9','*'
组成的字符串,算出这串字符所能代表的message的个数。
想法是用一个数组a[i]表示前i个字符所能表示的最大的message个数。然后a[i+1]就是在i个字符的基础上加一个字符,新加的字符可以单独解析,也可以和前一个合并,有两种情况。
接下来分类讨论就可以。
class Solution {
public:
int numDecodings(string s) {
if (s[0] == '0') return 0;
long m[100005] = {0};
m[0] = 1;
if (s[0] == '*') m[1] = 9;
else m[1] = 1;
for (int i = 1; i < s.length(); i++) {
if (s[i-1] == '1') {
if (s[i] != '*' && s[i] != '0') m[i+1] = m[i]+m[i-1];
else if (s[i] == '0') m[i+1] = m[i-1];
else if (s[i] == '*') m[i+1] = 9*m[i]+9*m[i-1];
} else if (s[i-1] == '2') {
if (s[i]-'0' <= 6 && s[i]-'0' >= 1) m[i+1] = m[i]+m[i-1];
else if (s[i] == '0') m[i+1] = m[i-1];
else if (s[i] == '*') m[i+1] = 9*m[i]+6*m[i-1];
else m[i+1] = m[i];
} else if (s[i-1] == '*') {
if (s[i] == '0') m[i+1] = 2*m[i-1];
else if (s[i] == '*') m[i+1] = 9*m[i]+15*m[i-1];
else if (s[i]-'0' <= 6 && s[i]-'0' >= 1) m[i+1] = m[i]+2*m[i-1];
else m[i+1] = m[i]+m[i-1];
} else {
if (s[i] == '*') m[i+1] = 9*m[i];
else if (s[i] == '0') return 0;
else m[i+1] = m[i];
}
if (m[i+1] > 1000000007) m[i+1] %= 1000000007;
}
// for (int i = 0; i < s.length(); i++) {
// cout << m[i] << endl;
// }
return m[s.length()];
}
};
别人的代码
class Solution {
public:
int numDecodings(string s) {
if (s.empty())
return 0;
long first = 1, second = 0;
if (s[0] == '*')
second = 9;
else if (s[0] > '0' && s[0] <= '9')
second = 1;
for (int i = 1; i < s.size();i++) {
long temp = 0;
if (s[i] == '*') {
temp = second*9;
if (s[i-1] == '*')
temp += first*15;
else if (s[i-1] == '1')
temp += first*9;
else if (s[i-1] == '2')
temp += first*6;
}
else {
temp = s[i] == '0'?0:second;
if (s[i-1] == '*') {
if (s[i] >= '0' && s[i] <= '6')
temp += 2*first;
else
temp += first;
}
else if ((s[i-1] == '1')||(s[i-1] == '2' && s[i] >= '0' && s[i] <= '6'))
temp+=first;
}
first = second;
second = temp%1000000007;
}
return second;
}
};
这个方法的想法的基础也是动态规划,不过做了一些优化。
因为a[i]的值只可能由a[i-1],a[i-2]导出,所以只需要保存这两个值(也就是代码中的first,second)就可以。
另外他的分类方法也比我的简单,再一次感觉自己蠢爆。。。