简体   繁体   English

如何改进此代码以查找数组的 k 个最大元素?

[英]How to improve this code for finding the k largest elements of an array?

The following code to find the k largest elements of an array is causing a TLE error.以下用于查找数组的 k 个最大元素的代码会导致 TLE 错误。 How can I optimize it to make it run faster?如何优化它以使其运行得更快?

import heapq    
for _ in range(int(input())):         
    n,k=map(int,input().split())   
    lists=list(map(int,input().split()))  
    
    heapq.heapify(lists)       
    
    for i in range(k+1):
        klargest=heapq.nlargest(i,lists)  
    
    print(*klargest)  
for i in range(k+1):
   klargest=heapq.nlargest(i,lists)  

The time complexity of each klargest operation is O(k*log n)) where n is the number of elements in heap.每个 klargest 操作的时间复杂度为 O(k*log n)),其中 n 是堆中元素的数量。 In the above code snippet, this operation is running for k+1 times for the values [0,k].在上面的代码片段中,对于值 [0,k],此操作运行了 k+1 次。

Calculating the time for the loop:计算循环时间:

iteration value (Time)迭代值(时间)

i == 0 (0*log(n)) i == 0 (0*log(n))

i == 1 (1*log(n)) i == 1 (1*log(n))

i == 2 (2*log(n)) i == 2 (2*log(n))

.... ……

i == k-1 ((k-1)*log(n)) i == k-1 ((k-1)*log(n))

i == k ((k)*log(n)) i == k ((k)*log(n))

Total time will be the sum of time taken in each operation = (0.log(n)) + (1*log(n)) +.... + ((k-1)*log(n)) + ((k)*log(n))总时间将是每次操作所用时间的总和 = (0.log(n)) + (1*log(n)) +.... + ((k-1)*log(n)) + ( (k)*log(n))

Total time = (0+1+2...+(k-1)+k) log(n) = ((k (k+1))/2)*log(n)总时间 = (0+1+2...+(k-1)+k) log(n) = ((k (k+1))/2)*log(n)

Total time ~~ O(k^2*(log(n)))总时间~~ O(k^2*(log(n)))

That's why the above code results in TLE.这就是为什么上面的代码会导致 TLE。

OPTIMISED APPROACH:优化方法:

import heapq    
for _ in range(int(input())):         
    n,k=map(int,input().split())   
    lists=list(map(int,input().split()))  
    
    heapq.heapify(lists)       
    
    for i in range(n-k):
        heapq.heappop(lists)
    klargest = list(lists) # converting heap to list
    print(*klargest) 

As Inbuilt heap in python is min-heap.由于 python 中的内置堆是最小堆。 So the above code is popping out minimum nk elements from lists.所以上面的代码是从列表中弹出最少 nk 个元素。 Popping out each operation will take log(n) time.弹出每个操作将花费 log(n) 时间。 Thus total time will be ~~ (nk)*logn.因此总时间将为 ~~ (nk)*logn。 The remaining k elements in the heap are the klargest elements that we want to find.堆中剩余的 k 个元素是我们想要找到的 k 个最大元素。

Thus, the time complexity for the above solution is O((nk)*log(n)) == O(nlog(n)) which is a optimised time complexity.因此,上述解决方案的时间复杂度为 O((nk)*log(n)) == O(nlog(n)) ,这是优化的时间复杂度。

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

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