题目传送:https://leetcode.cn/problems/decode-ways/
运行效率
代码如下:
public static int numDecodings(String s) {
//hashmap的作用就是当缓存,提升查询速度
HashMap<String, Integer> map = new HashMap<>();
return numDecodingsWithMap(s, map);
}
//递归解法
public static int numDecodingsWithMap(String s, HashMap<String, Integer> map) {
if (map.containsKey(s)) {
return map.get(s);
}
//处理边界情况
if (s.startsWith("0") || s.contains("00")) {
return 0;
}
if (s.length() == 1) {
map.put(s, 1);
return 1;
}
//当前字符串的最后一个字符
char c = s.charAt(s.length() - 1);
char c1 = s.charAt(s.length() - 2);
int lastTwoNum = (c1 - '0') * 10 + c - '0';
if (s.length() == 2) {
if (lastTwoNum % 10 == 0) {
if (lastTwoNum > 26) { //比如30
return 0;
} else { //比如20
return 1;
}
} else {
if (lastTwoNum > 26) { //比如27
return 1;
}else{ //比如23
return 2;
}
}
}
int num = 0;
//递归解法
String substring;
if (c == '0') {// 比如对于 1110来说,c==0, 于是0只能跟前面挨着的那个1进行组合成10,也就是J 剩下的就是看 11有多少种解码办法, 11可以被解码为AA或K
if (c1 <= '2') {
substring = s.substring(0, s.length() - 2);
num = numDecodingsWithMap(substring, map);
}
map.put(s, num);
return num;
} else {
if (c1 > '0' && c1 <= '2') { //比如对于121来说,c==1,那么就有2种组合办法
//①c可以跟前面挨着的那个2进行组合成21,即U,然后剩下的一个1倍解码成A, 所以最后解码结果是AU
if (lastTwoNum <= 26) { //最后两个字符组成的数字要小于等于26
substring = s.substring(0, s.length() - 2);
num = numDecodingsWithMap(substring, map);
map.put(substring, num);
}
//②c单独进行解码,1解码为A,然后剩下的12解码为L ,所以最后解码结果是LA
substring = s.substring(0, s.length() - 1);
int i = numDecodingsWithMap(substring, map);
map.put(substring, i);
num = num + i;
} else { //如果c1>2, 比如 134来说, 这个4就只能单独解码,而不能跟前面挨着的那个3进行组合
substring = s.substring(0, s.length() - 1);
num = numDecodingsWithMap(substring, map);
map.put(substring, num);
}
}
map.put(s, num);
return num;
}