丑数
丑数为仅有 2,3或5 的质因子的数。数列1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … 展示了前11个丑数。按照惯例,其中包括1。给定一个数字n,请你找出第n个丑数。
首先,如何判断一个数是否为丑数?将这个数分别除以2、3、5的最大可能次幂,如果最终得到1,则为丑数。
因为丑数的质因子仅为2、3、5,丑数数列的数将会被分为三组:
- 1x2, 2x2, 3x2, 4x2, 5x2, …
- 1x3, 2x3, 3x3, 4x3, 5x3, …
- 1x5, 2x5, 3x5, 4x5, 5x5, …
每一个子数列都是丑数本身与2、3、5相乘。因此我们可以利用类似合并排序一样通过合并三个子数列来得到所有丑数。
-
声明丑数数列: ugly[n]
-
初始化第一个丑数: ugly[0] = 1
-
初始化三个子数列索引,指向子数列的第一个元素: i2 = i3 = i5 = 0
-
初始化三个下一个丑数的可能值:
next_multiple_of_2 = ugly[i2] * 2;
next_multiple_of_3 = ugly[i3] * 3;
next_multiple_of_5 = ugly[i5] * 5;
-
填充dp数组
import time
def getNthUglyNo(n):
ugly = [0] * n
ugly[0] = 1
i2 = i3 = i5 = 0
next_multiple_of_2 = 2
next_multiple_of_3 = 3
next_multiple_of_5 = 5
for i in range(1, n):
ugly[i] = min(next_multiple_of_2,
next_multiple_of_3,
next_multiple_of_5)
if ugly[i] == next_multiple_of_2:
i2 += 1
next_multiple_of_2 = ugly[i2] * 2
if ugly[i] == next_multiple_of_3:
i3 += 1
next_multiple_of_3 = ugly[i3] * 3
if ugly[i] == next_multiple_of_5:
i5 += 1
next_multiple_of_5 = ugly[i5] * 5
return ugly[-1]
# Driver code
time_start = time.time()
no = getNthUglyNo(150)
time_end = time.time()
print('150th ugly no is', no)
print('cost ', (time_end - time_start) * 1000, 'ms')
由于时间复杂度为O(n), 所以用时已经没办法打印出来了。
斐波那契数列
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
用数学术语来描述:
Fn = Fn-1 + Fn-2
种子数:F0 = 0, F1 = 1
给定一个数n,求第n个斐波那契数
和上一题类似,由下往上构建dp数组
def getNthFiboNo(n):
Fibo = [0] * (n)
Fibo[0] = 0
Fibo[1] = 1
if n <= 1:
return Fibo[n]
for i in range(2, n):
Fibo[i] = Fibo[i - 2] + Fibo[i - 1]
return Fibo[-1]
no = getNthFiboNo(9)
print('9th fibonacci no is', no)
# 9th fibonacci no is 21