难度:中等
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”
提示:
定义 dp 数组,dp[i] 表示以第 i 个字符结尾的子串的 总 翻译方法;
如果 若
x
i
x_i
xi 和
x
i
−
1
x_{i-1}
xi−1 组成的两位数字可以被翻译,则 dp[i]=dp[i−1]+dp[i−2];否则 dp[i]=dp[i−1]。
00, 01, 02, ⋯),因此区间为 [10,25]。观察上面的 状态转移方程,发现 dp[i] 只与 前两位 dp[i - 1]、 dp[i - 2] 有关,所以可以进行空间优化,我们使用 pre1 代替 dp[i - 1], pre2 代替 dp[i - 2],cur 代替 dp[i]:
c
u
r
=
{
p
r
e
1
+
p
r
e
2
,
10
x
i
−
1
+
x
i
∈
[
10
,
25
]
p
r
e
1
,
10
x
i
−
1
+
x
i
∈
[
0
,
10
)
∪
(
25
,
99
]
cur=
当前 状态 cur 处理完, pre 和 pre2 共同前移一位,进而可以表示为:
p
r
e
1
=
{
p
r
e
1
+
p
r
e
2
,
10
x
i
−
1
+
x
i
∈
[
10
,
25
]
p
r
e
1
,
10
x
i
−
1
+
x
i
∈
[
0
,
10
)
∪
(
25
,
99
]
pre1=
p
r
e
2
=
{
p
r
e
1
−
p
r
e
2
,
10
x
i
−
1
+
x
i
∈
[
10
,
25
]
p
r
e
1
,
10
x
i
−
1
+
x
i
∈
[
0
,
10
)
∪
(
25
,
99
]
pre2=
按位遍历该数字,从 左到右 和 右到左 是相同的,本方法使用 右到左 。
初始化:pre1 = pre2 = 1,即 “无数字” 和 “第 1 位数字” 的翻译方法数量均为 1 。
C++
class Solution {
public:
int translateNum(int num) {
if(num < 10) return 1;
int pre1 = 1, pre2 = 1;
while(num >= 10){
int tmp = num % 100;
if(tmp / 10 > 0 && tmp <= 25) {
pre1 += pre2;
pre2 = pre1 - pre2;
}else{
pre2 = pre1;
}
num /= 10;
}
return pre1;
}
};
Java
class Solution {
public int translateNum(int num) {
if(num < 10) return 1;
int pre1 = 1, pre2 = 1;
while(num >= 10){
int tmp = num % 100;
if(tmp / 10 > 0 && tmp <= 25) {
pre1 += pre2;
pre2 = pre1 - pre2;
}else{
pre2 = pre1;
}
num /= 10;
}
return pre1;
}
}

n 为字符串 s 的长度。题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!