此题说明了:
- 可以尝试用空间换取时间
- 像丑数这种越来越稀疏的问题,越到后面越体现出算法优化的重要性
《剑指offer34题》只包含因子2、3、5的数叫丑数,找出前1500个丑数。
1.暴力解法
逐一判断是否是丑数
def is_ugly_num(num):
while num % 2 == 0:
num //= 2
while num % 3 == 0:
num //= 3
while num % 5 == 0:
num //= 5
if num == 1:
return True
else:
return False
@timing
def get_ugly_num2(index = 1500):
i = 0
num = 2
while i < index:
while not is_ugly_num(num):
num += 1
# print(num)
i += 1
num += 1
但是如果你知道第1500个丑数是1412006979354108748474554421102313931675676955925788762341700965431346915180599249952936960497614998485448932749141998289061648432939195473813276544243473053215398045741358060286316036246351763861878679739417265182867456
的话,您估计也不会用这种方法,丑数的增长几乎的指数型的。丑数500个以后越来越稀疏,暴力破解每找一个都要s级的时间,越来越慢。
500个之前的差别:
get_ugly_num function took 0.002 s
get_ugly_num2 function took 3.665 s
2.正向求解的方法,秒解,暴力破解几分钟还是没有完,我等不及了
面试题之丑数的C++实现求解(孤陋寡闻了,才知道丑数这么high的东东)
@timing
def get_ugly_num(index = 1500):
if index < 1:
return
ugly_list = [1]
current_ugly_index = 0
index_2 = 0
index_3 = 0
index_5 = 0
num_2 = 1
num_3 = 1
num_5 = 1
while current_ugly_index < index :
while num_2 <= ugly_list[current_ugly_index]:
index_2 += 1
num_2 *= 2
while num_3 <= ugly_list[current_ugly_index]:
index_3 += 1
num_3 *= 3
while num_5 <= ugly_list[current_ugly_index]:
index_5 += 1
num_5 *= 5
min_num = min((num_2,num_3,num_5))
ugly_list.append(min_num)
current_ugly_index += 1
# print(min_num)