难度:中等
给定一个数字,我们按照如下规则把它翻译为字符串: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=\begin{cases}pre1+pre2&,10x_{i-1}+x_i\in[10,25]\\pre1&,10x_{i-1}+x_i\in[0,10)\cup(25,99]\end{cases} cur={pre1+pre2pre1,10xi−1+xi∈[10,25],10xi−1+xi∈[0,10)∪(25,99]
当前 状态 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=\begin{cases}pre1+pre2&,10x_{i-1}+x_i\in[10,25]\\pre1&,10x_{i-1}+x_i\in[0,10)\cup(25,99]\end{cases} pre1={pre1+pre2pre1,10xi−1+xi∈[10,25],10xi−1+xi∈[0,10)∪(25,99]
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=\begin{cases}pre1-pre2&,10x_{i-1}+x_i\in[10,25]\\pre1&,10x_{i-1}+x_i\in[0,10)\cup(25,99]\end{cases} pre2={pre1−pre2pre1,10xi−1+xi∈[10,25],10xi−1+xi∈[0,10)∪(25,99]
按位遍历该数字,从 左到右
和 右到左
是相同的,本方法使用 右到左
。
初始化: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—力扣专栏,每日更新!