此題說明了:
- 可以嘗試用空間換取時間
- 像丑數這種越來越稀疏的問題,越到后面越體現出算法優化的重要性
《劍指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)