繁体   English   中英

找到最大k个整数的时间复杂度是多少?

[英]What is the Time Complexity of finding the max k integers?

def max_k_sort(k, nums):
    # sort nums first using timsort
    # add O(n*log(n)) time complexity
    sorted_nums = sorted(nums)

    return sorted_nums[-1*k:len(nums)]

def max_k(k, nums):
    # build initial max number list
    max_nums = {}

    # add O(k) time complexity?
    i = 0
    while i < k:
        max_nums[i] = 0
        i += 1

    # add O(n) time complexity?
    least_max_key = min(max_nums, key=max_nums.get)
    least_max = max_nums[least_max_key]

    # add O(n) time complexity?
    for n in nums:
        if n > least_max:
            max_nums[least_max_key] = n
            least_max_key = min(max_nums, key=max_nums.get)
            least_max = max_nums[least_max_key]

    return max_nums.values()

print(max_k(5, [2, 8, 4, 9, 0, 12, 12, 6, 5]))

我不太确定这段代码的时间复杂性。 任务是从未排序的整数数组返回最大k数。 数组中的每个数字都在[0,10000)范围内。 我的目标是有一个明显的解决方案max_k_sort(k,nums)以O(n * log(n))时间复杂度完成任务,另一个方法max_k(k,nums)以O(n)时间复杂度完成任务其中n是传递的整数数,k是要查找的最大值数。 我不禁想知道是否有办法返回以O(n)时间复杂度排序的最大值。

for n in nums:
        if n > least_max:
            max_nums[least_max_key] = n
            least_max_key = min(max_nums, key=max_nums.get) # this is O(k)
            least_max = max_nums[least_max_key]

你进行了n次O(k)操作,所以你的第二个函数的复杂度是O(n * k)。

假设您希望输出按排序顺序,这可以通过创建一个k -sized堆并将所有内容推送到O(n * log(k))来最容易地完成。 这是在heapq.nlargest为您实现的。

import heapq

heapq.nlargest(5, [2, 8, 4, 9, 0, 12, 12, 6, 5])
Out[4]: [12, 12, 9, 8, 6]

如果您希望输出按排序顺序,则技术上可以在O(n)中完成。 存在算法 (和python 实现 )以在线性时间内找到数组中的第k个最大元素; 很容易看出,再一次通过数组将允许你构建一个所有数字k和更大的数组,给出整体O(n)。

Python 状态列表操作中列表操作的时间复杂度为O(N log N)。

切片是O(k)

所以:

def max_k(k, nums):
    nums.sort(reverse=True)
    return nums[0:k]

O(k)+ O(n log n)是O(n log n)其中O(k)小于O(n log n)

>>> max_k(5, [2, 8, 4, 9, 0, 12, 12, 6, 5])
[12, 12, 9, 8, 6]

实际上,请尝试计时:

import heapq
def max_k1(k, nums):
    nums.sort(reverse=True)
    return nums[0:k]

def max_k2(k, nums):
    return heapq.nlargest(k, nums)    

if __name__ == '__main__':
    import timeit
    for f in (max_k1, max_k2):
        li=[2, 8, 4, 9, 0, 12, 12, 6, 5]
        print f.__name__, timeit.timeit('f(5, li)', setup='from __main__ import f, li')  

打印:

max_k1 0.240165948868
max_k2 4.96488595009

因此sort和slice比heapq快20倍。


根据评论:

import heapq
def max_k1(k, nums):
    nums.sort(reverse=True)
    return nums[0:k]

def max_k2(k, nums):
    return heapq.nlargest(k, nums)   

def max_k3(k, nums):
    return sorted(nums, reverse=True)[0:k]    

if __name__ == '__main__':
    import timeit
    for f in (max_k1, max_k2, max_k3):
        li=[2, 8, 4, 9, 0, 12, 12, 6, 5]
        print f.__name__, timeit.timeit('f(5, li)', setup='from __main__ import f, li')    

max_k1 0.242296934128
max_k2 4.52635192871
max_k3 0.332237005234

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM