Leetcode(91) Decode Ways

Description

A message containing letters from A-Z is being encoded to numbers using the following mapping:

1
2
3
4
'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:

1
2
3
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

Example 2:

1
2
3
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).

解法

这道题首先考虑采用DFS解,但是发现有重叠子问题的情况,改用动态规划。数组dp[i]代表s[0,i-1]的解码个数情况。

对于到每一位为止的解码个数结果,分为4种情况考虑:

1.最后两位的结果大于等于10小于等于26(除10与20):

dp[i+1] = dp[i]+dp[i-1](最后的两位可拆开解码)

2.最后两位为10或20

dp[i+1] = dp[i-1](最后两位必须捆绑,等于i-2位的解码个数)

3.其他:

dp[i+1] = dp[i](最后两位必须解绑,等于i-1位的解码个数)

4.末尾为0且大于20,或为00:

dp[i+1] = 0(无解)

可进行逻辑简化,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int numDecodings(String s) {
if (s.length() == 0 || s.charAt(0) == '0') {
return 0;
}
int dp[] = new int[s.length() + 1];
dp[0] = dp[1] = 1;
for (int i = 1; i < s.length(); i++) {
int tmp = Integer.parseInt(s.substring(i - 1, i + 1));
if (tmp >= 10 && tmp <= 26) {
dp[i + 1] += dp[i - 1];
}
if (tmp % 10 != 0) {
dp[i + 1] += dp[i];
}
}
return dp[s.length()];
}
}