《剑指offer》python实现系列,全目录
题目描述:
给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成“a”,1翻译成“b”,……,25翻译成“z”。
一个数字可能有多个翻译。例如:12258有5种不同的翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”和“mzi”。
请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
第一想法:
一个数字能分割成个0~25之间的数字有多少种分法。
整不出来
剑指offer方法:
走一步或两步,属于青蛙跳台阶/爬楼梯/斐波那契数列问题,不过此题加了限制2个数字组合要在0-25之间,需要做个判断。
if 第 i 位和第 i+1 两位数字拼接起来的数字在0-25之间时
$F(i) = F(i+1) + F(i+2) $
else
$F(i) = F(i + 1) $
$F(i) $ 表示从左到右从第 i 位开始翻译的分法。
为了便于理解,贴近斐波那契额数列公式,从右边开始编号0。
举例来说,ABCD表示四个数字,ABCD下标是3210.要分解ABCD,可以
[AB,CD],AB是一种,CD有F(1)种分法,(若AB在0-25之间,否则就没有这种分法)
[A,BCD],A是一种,BCD有F(2)种分法
所以:
if 第 i 位和第 i-1 两位数字拼接起来的数字在0-25之间时
$F(i) = F(i-1) + F(i-2) $
else
$F(i) = F(i - 1) $
$F(i) $ 表示从右到左到第 i 位(从右边数)结束的分法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Solution:
def translate(self, num):
def Fibonacci(numbers):
#计算此题的斐波那契额数列
length = len(numbers)
if length==0:
return [0]
if length == 1:
return [1]
else:
flist = [0]*length #用于存储斐波那契额数列结果
flist[0]=1
if 10<=numbers[-2]*10+numbers[-1] <=25:
flist[1] = 2
else:
flist[1] = 1
for i in range(2, len(numbers)):
if 10<=10*numbers[-i-1]+numbers[-i] <=25:
flist[i] = flist[i-1]+flist[i-2]
else:
flist[i] = flist[i-1]
return flist
if num<0:
return 0
numlist = list(map(int,str(num))) #将int转为list
return Fibonacci(numlist)[-1]