我在Python上学习算法课程。我在Big-O表示法上有点挣扎。问题是创建一个线性函数来找到k-最小的数字,并将函数改进为对数线性。我已经制作了这个:
import random
import timeit
def linear_find_smallest(values):
smallest = len(values)
for i in values:
if smallest > i != 0:
smallest = i
return smallest
def loglinear_find_smallest(values):
values.sort()
smallest = len(values)
for i in values:
if smallest > i != 0:
smallest = i
del values[values.index(i):]
return smallest
if __name__ == '__main__':
values = random.sample([i for i in range(1, 10000)], len(range(1, 10000)))
t = timeit.Timer("linear_find_smallest(%s)" % str(values),
setup="from __main__ import linear_find_smallest")
print("Lineair: found in %f seconds" % t.timeit(number=1000))
t = timeit.Timer("loglinear_find_smallest(%s)" % str(values),
setup="from __main__ import loglinear_find_smallest")
print("Log linear: found in %f seconds" % t.timeit(number=1000))
然而,线性函数在1.614513秒内运行,而(我假设)日志线性函数在8.463193秒内运行。有人能告诉我,如果我在这里做错了吗?
答案 0 :(得分:1)
首先,在排序后,您可以返回第一个值,这是排序定义中最小的值。
def loglinear_find_smallest(values):
values.sort()
return values[0]
现在关于复杂性的真正问题。如果给出一个任意列表,那么线性搜索(O(n)
)是找到最小值的最佳方法。这是因为无论您的搜索策略是什么,有人都可以为您的函数创建一个输入,以便您检查最小值的第一个n-1
位置不是最小值。
话虽如此,没有什么能比线性搜索更快。特别是,日志线性(O(n log n)
)实际上保证要慢,因为您正在执行更多操作。我真的不确定你是如何/为什么你对日志线性感到困惑表面上比线性更快。也许你把它与logarthmic(O(log n)
)混淆了?