题目
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
'A' -> 1
'B' -> 2
...
'Z' -> 26
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“11106” 可以映射为:
“AAJF” ,将消息分组为 (1 1 10 6)
“KJF” ,将消息分组为 (11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 “06” 不能映射为 “F” ,这是由于 “6” 和 “06” 在映射中并不等价。
给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。
核心
爬楼梯,可以一步,可以两步,请问…
本质上来说,两个东西不都一样么。不过多了点限制
- 不能以
0
开头 - 两位数值不能大于
26
追根究底,还是逃不过 f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n) = f(n-1) + f(n-2) f(n)=f(n−1)+f(n−2),不过,两部分是存在特殊条件的。
f ( n − 1 ) f(n-1) f(n−1)
至少不能是0
,所以正确结果是
f
(
n
−
1
)
=
{
0
c
[
n
−
1
]
=
’0’
f
(
n
−
2
)
+
f
(
n
−
3
)
otherwise
f(n-1) = \left\{\begin{matrix} 0 & c[n-1] = \text{'0'} \\ f(n-2) + f(n-3) & \text{otherwise} \end{matrix}\right.
f(n−1)={0f(n−2)+f(n−3)c[n−1]=’0’otherwise
f ( n − 2 ) f(n-2) f(n−2)
f ( n − 2 ) = { f ( n − 3 ) + f ( n − 4 ) 10 ≤ int(c[n-3],c[n-3]) ≤ 26 0 otherwise f(n-2) = \left\{\begin{matrix} f(n-3) + f(n-4) & 10 \le \text{int(c[n-3],c[n-3])} \le 26 \\ 0 &\text{otherwise} \end{matrix}\right. f(n−2)={f(n−3)+f(n−4)010≤int(c[n-3],c[n-3])≤26otherwise
解答
缓存
class Solution {
public int numDecodings(String s) {
int length = s.length();
int[] result = new int[length + 1];
result[0] = 1;
char lastChar;
char lastBefore;
for (int i = 1; i < length+1; i++) {
if((lastChar = s.charAt(i - 1)) != '0'){
result[i] += result[i-1];
}
if(i > 1 && (lastBefore = s.charAt(i-2)) != '0' && (10 * (lastBefore - '0') + (lastChar - '0')) <= 26){
result[i] += result[i-2];
}
}
return result[length];
}
}
累计
斐波那契本来就能够从小累大,这个同样可以。
class Solution {
public int numDecodings(String s) {
int length = s.length();
int lastBefore = 0;
int last = 1;
int current = 0;
for (int i = 1; i < length+1; i++) {
current = 0;
if(s.charAt(i - 1) != '0'){
current += last;
}
if(i > 1 && s.charAt(i-2) != '0' && (10 * (s.charAt(i-2) - '0') + (s.charAt(i-1) - '0')) <= 26){
current += lastBefore;
}
lastBefore = last;
last = current;
}
return current;
}
}