https://leetcode.cn/problems/decode-ways/description/
那么我们可以设置一个数组来存储前n个数的编码的总方法数
int dp[] = new int[s.length()];
我们每次插入数的时候有多种可能
- 当这个数为0时判断上一个数是否能与0一起构成编码
- 当这个数不是0的时候,也需要判断上一个数是否能与该数一起构成编码
dp[2] = 3 dp[3] = 3 dp[4] = 6
例如前3个数为1,2,3 可分为 [1,2,3] [12,3] [1,23]如果第四个数为1时
我们可以看到31>26所以新加入的编码方法总数不变[1,2,3,1] [12,3,1] [1,23,1]
如果添加第5个数为1那么新加入的编码可以看作在[1,2,3] [12,3] [1,23]的基础上加了一个11 : [1,2,3,11] [12,3,11] [1,23,11] 和在[1,2,3,1] [12,3,1] [1,23,1]的基础上加了一个1 :[1,2,3,1,1] [12,3,1,1] [1,23,1,1]
然后我们可以得到大致的一个规律
- 当这个数为0时,上一个数能与0一起构成编码
dp[ i ] = dp[ i - 2 ]
- 当这个数为0时,上一个数不能与0一起构成编码
return 0;
- 当这个数不是0的时候,上一个数能与该数一起构成编码
dp[ i ] = dp[ i - 1 ] + dp[ i - 2 ]
- 当这个数不是0的时候,上一个数不能与该数一起构成编码
dp[ i ] = dp[ i - 1 ]
然后对于一些稍微特殊情况进行判断,代码如下:
public static int numDecodings(String s) {
int int_s[] = new int[s.length()];
int dp[] = new int[s.length()];
int_s[0] = (int) s.charAt(0) - 48;
dp[0] = 1;
if (int_s[0] == 0) {
dp[0] = 0;
}
int num = dp[0];
for (int i = 1; i < s.length(); i++) {
int_s[i] = (int) s.charAt(i) - 48;
if (int_s[i] == 0) {
if (int_s[i - 1] <= 2 && int_s[i - 1] > 0) {//当这个数为0时,上一个数能与0一起构成编码
if (i == 1) {
dp[i] = 1;
continue;
}
dp[i] = dp[i - 2];
num = dp[i];
} else {//当这个数为0时,上一个数不能与0一起构成编码
return 0;
}
} else {//这个数不是0
if (int_s[i - 1] * 10 + int_s[i] <= 26) {//上一个数能与该数一起构成编码
if (i == 1) {
dp[i] = 2;
num = dp[i];
continue;
}
dp[i] = dp[i - 1] + dp[i - 2];
num = dp[i];
} else {//上一个数不能与该数一起构成编码
dp[i] = dp[i - 1];
num = dp[i];
}
}
}
return num;
}