【LeetCode & 剑指offer刷题】动态规划与贪婪法题3:剑指Offer-46:把数字翻译成字符串
【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)
剑指Offer-46:把数字翻译成字符串
题目:
给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成“a”,1翻译成“b”,……,11翻译成“1”,……,25翻译成“z”。一个数字可能有多个翻译。例如:12258有5种不同的翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
/*
问题:把数字翻译成字符串
方法:动态规划
将数字number转成字符串s,方便引用各位
dp[i]表示以s[0~i]的数字翻译成字符串的方法数
则有
dp[i] = dp[i - 1] + g*dp[i - 2]
(当s[i-1,i]能组合在一起翻译成有效字符时,g=1,否则g=0)
上式右边分别对应两种分隔方法:
s[0~i-1] + s[i](共dp[i-1]种)
s[0~i-2] + s[i-1,i](如果g=1,该分隔有效,共dp[i-2]种)
本题类似:climb stairs
*/
using
namespace
std
;
#include <iostream>
#include <vector>
#include <string>
int
translation
(
int
number
)
{
if
(
number
<
0
)
return
0
;
string s
=
to_string
(
number
);
//把数字转成字符串,方便引用各位数字
int
n
=
s
.
size
();
if
(
n
==
1
)
return
1
;
//因为通项公式中最少须有两个初始值
vector
<
int
>
dp
(
n
);//一般dp中序号与实际的序号对应起来,决定分配n空间还是n+1空间
dp
[
0
]
=
1
;
//递推公式需要两个初值
int
temp
=
(
s
[
0
]
-
'0'
)*
10
+
s
[
1
]
-
'0'
; //构造组合数
if
(temp>=10 && temp<=25
)
dp
[
1
]
=
2
;
else
dp
[
1
]
=
1
;
int
g
=
0
;
for
(
int
i
=
2
;
i
<=
n
-
1
;
i
++)
{
int
temp
=
(
s
[
i
-
1
]
-
'0'
)*
10
+
s
[
i
]
-
'0'
;
if
(
temp
>=
10
&&
temp
<=
25
)
g
=
1
;
else
g
=
0
;
dp
[
i
]
=
dp
[
i
-
1
]
+
g
*
dp
[
i
-
2
];
//假设dp[0]=1,则从dp[2]开始满足通项公式
}
return
dp
[
n
-
1
];
}