Problem:
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
Example 1:
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
思路:
用DP算法。设数组size为n,初始化dp[n+1]数组,其中dp[i]表示到第i个字符所有的解码总数,最后返回dp[n]即可。注意第i个字符对应的数组下标为i-1。分以下几种情况讨论:
- 如果当前位置为0,前一位置为0或大于2,则无法解码;
- 如果当前位置为0,前一位置值为1或2,则dp[i] = dp[i-2];
- 如果当前位置不为0,前一位置为0,则dp[i] = dp[i-1];
- 如果当前位置与前一位置都不为0,且组成的2位数大于26,则dp[i] = dp[i-1];
- 如果当前位置与前一位置都不为0,且组成的2位数不大于26,则可以单独解码与合并起来解码,则dp[i] = dp[i-1] + dp[i-2]。
Solution:
int numDecodings(string s) {
if (s.empty() || s[0] - '0' == 0) return 0;
int n = s.size();
vector<int> dp(n+1);
//赋初值
dp[0] = 1; //表示字符串为空情况,与上面的有区别,额外初始化
dp[1] = 1; //表示字符串只含有1个字符的情况
for (int i = 2; i < n + 1; i++) {
int cur = s[i-1] - '0';
int prev = s[i-2] - '0';
//if (cur == 0 && prev == 0 || cur == 0 && prev > 2) return 0;
//else if (cur == 0) dp[i] = dp[i-2];
if (cur == 0) {
if (prev == 0 || prev > 2) return 0;
else dp[i] = dp[i-2];
}
else if (prev == 0 || prev * 10 + cur > 26) dp[i] = dp[i-1];
else dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
性能:
Runtime: 4 ms Memory Usage: 8.7 MB