Description:
A message containing letters from A-Z
is being encoded to numbers using the
following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1
2) or "L"
(12).
The number of ways decoding "12"
is 2.
Solution:
本来考虑的是每次遇到11-19和21-26的数字就乘以2,但是后来发现如果遇到了1121的情况就很难用乘以2的方式表达。以及遇到10和20需要固定住这两位数字。
换一个方式来,用状态转移来表达。
dp[i]表示到了第i位一共有多少种情况,有这么几种转移的方式:
1. nums[i]在11-19和21-26之间,那么dp[i] = dp[i-1] + dp[i-2]
2. nums[i]是10或者20,dp[i] = dp[i-2]
3. 其余情况dp[i] = dp[i-1]
import java.util.*;
public class Solution {
public int numDecodings(String s) {
if (s.equals(""))
return 0;
int len = s.length();
// 包含0,00,30,40到90的情况
for (int i = 0; i < len; i++) {
if (s.charAt(i) == '0') {
if (i == 0 || s.charAt(i - 1) == '0' || s.charAt(i - 1) >= '3')
return 0;
}
}
// 放在for循环的后面,是为了防止出现“0”的情况
if (s.length() == 1)
return 1;
int[] dp = new int[len];
dp[0] = 1;
char ch1, ch2;
int temp;
ch1 = s.charAt(0);
ch2 = s.charAt(1);
temp = (ch1 - '0') * 10 + (ch2 - '0');
if (canDivide(temp))
dp[1] = 2;
else
dp[1] = 1;
for (int i = 2; i < len; i++) {
ch1 = s.charAt(i - 1);
ch2 = s.charAt(i);
temp = (ch1 - '0') * 10 + (ch2 - '0');
if (canDivide(temp))
dp[i] = dp[i - 1] + dp[i - 2];
else if (temp == 10 || temp == 20)
dp[i] = dp[i - 2];
else
dp[i] = dp[i - 1];
}
return dp[len - 1];
}
boolean canDivide(int t) {
if (t >= 11 && t <= 19)
return true;
else if (t >= 21 && t <= 26)
return true;
return false;
}
}