编辑:抱歉!我似乎不经意地复制粘贴了相同的代码。
问题:
给出从0到N-1的数字列表,您的工作就是找到遗失的数字 数。你的程序应该采用整数列表并返回一个 单个整数(缺少的数字)。
即。输入[0, 1, 3, 4, 5]
应返回2
。
我找到了两个解决方案,一个在O(n)中,一个在(On ^ 2)中。
O(n)解决方案
def alt_find_missing(input_list):
input_sum = sum(input_list)
range_sum = sum([i for i in range(min(input_list), max(input_list)+1)])
return range_sum - input_sum
O(n ^ 2)解决方案
def find_missing(input_list):
input_set = set(input_list)
for i in range(min(input_list), max(input_list)+1):
if i not in input_set:
return i
但是,在多个timeit
测试中,O(n ^ 2)解决方案的运行速度比O(n)快:
List with 4 elements, using for ... in set (x 1 000 000)
1.1550223514080038
List with 4 elements, using difference of sums (x 1 000 000)
1.391524411772641
List with 100 elements, using for ... in set (x 1 000 000)
8.43574248785071
List with 100 elements, using difference of sums (x 1 000 000)
8.94695660741872
List with 1000 elements, using for ... in set (x 100 000)
8.1138781071155
List with 1000 elements, using difference of sums (x 100 000)
8.383110816298519
为什么会这样?
答案 0 :(得分:2)
第二种算法不是O(n ^ 2)。集查找是O(1)并且迭代集合是O(n)。因此,两种算法之间的差异是由于不同的常数因素造成的。
这是一个简短的脚本,显示了两个函数的线性行为
import timeit
from functools import partial
from matplotlib import pyplot as plt
def alt_find_missing(input_list):
input_sum = sum(input_list)
range_sum = sum([i for i in range(min(input_list), max(input_list)+1)])
return range_sum - input_sum
def find_missing(input_list):
input_set = set(input_list)
for i in range(min(input_list), max(input_list)+1):
if i not in input_set:
return i
t1=[]
t2=[]
rng=range(10000,1000000,10000)
for n in rng:
func1=partial(find_missing,range(n))
func2=partial(alt_find_missing,range(n))
t1.append(timeit.timeit(func1,number=5))
t2.append(timeit.timeit(func2,number=5))
plt.plot(rng,t1, label='Find missing')
plt.plot(rng,t2, label='Alt find missing')
plt.ylabel('Execution time')
plt.xlabel('Problem size')
plt.legend()
plt.show()
结果对我来说看起来非常线性:)当然在某些问题大小上会出现一些特殊情况,但没有什么可以将结果显着地抛出线性区域。