Top k Largest Numbers

这道题的错也充分显示了基础知识不扎实导致的。
非常值得一记。

544. Top k Largest Numbers

Given an integer array, find the top k largest numbers in it.

Example

Given [3,10,1000,-99,4,100] and k = 3.
Return [1000, 100, 10].
思考过程:
O(N) 一遍nums是免不了的,所以关键就在于top k上。top k会被定义为一个数组。在本题的答案中,其实隐含了要求让所有的K个数都降序排列,但在这点上,题目并没有真正的要求。所以sorting是一个必要的过程。关键是怎么sort, 什么时候sort, 还有谁sort

暴力解法。
每次都遍历k数组,然后找到k数组中的最小数的index, 然后replace.
然后再在最后输出答案的时候,list.sort(reverse = True)
毫无疑问。time limit exceeded.
因为这样做的最差的时间复杂度为 O(N^2) 如果 K ~= len(nums)

聪明的解法。
Scenario: 想来,如果我的nums是一个streaming, 是不是可以让它在通过了某一个filter或者component的时候可以自动过滤出满足某一个criteria的值

priority_queue:
heapq:
heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2] for all k, counting elements from zero.

我的答案。complexity O(NLogN)
heapq的用法,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    def topk(self, nums, k):
        # write your code here
        if len(nums) == k:
            nums.sort(reverse = True)
            return nums
            
        topkFilter = [-sys.maxint - 1] * k
        heapq.heapify(topkFilter)
        
        for n in nums:
            heapq.heappushpop(topkFilter, n)
            
        return heapq.nlargest(k, topkFilter)

看了geeksforgeeks的答案,实在又颠覆了三观。
https://www.geeksforgeeks.org/k-largestor-smallest-elements-in-an-array/



这个解法很有意思。
Method 5(Use Oder Statistics)
1) Use order statistic algorithm to find the kth largest element. Please see the topic selection in worst-case linear time O(n)
2) Use QuickSort Partition algorithm to partition around the kth largest number O(n).
3) Sort the k-1 elements (elements greater than the kth largest element) O(kLogk). This step is needed only if sorted output is required.

Time complexity: O(n) if we don’t need the sorted output, otherwise O(n+kLogk)
kth largest item in the list
利用quick sort里面partition的概念,唯一改了一小丢丢的是这次需要找到Partition的位置是固定的。只要找到这个位置以后就可以Output, 不需要像quick sort那要一脑门的走到底。。大哥走在前面,走着走着,跟着的小弟爬到半山腰说,头疼,高反,走不动了。然后就停在了海拔4000米的地方。这个4000米就是这个k.


最最根本回去还是算二分法的影射吧,当满足了某个条件的时候,便放弃不满足条件的部分。废话不多说了,我去implement一下下。


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def kthlargest(nums, k):
    if len(nums) == k:
        return nums
    elif len(nums) < k:
        return []
    else:
        partition = kthlargestUtil(nums, k, 0, len(nums)-1)
        return nums[0:k]

def kthlargestUtil(nums, k, start, end):
    pivot = nums[start]
    pstart, pend = start + 1, end
    while(pstart < pend):
        while nums[pstart] >= pivot and pstart < end:
            pstart += 1

        while nums[pend] < pivot and pend > start:
            pend -= 1

        if pstart < pend:
            nums[pstart], nums[pend] = nums[pend], nums[pstart]
    
    nums[start], nums[pend] = nums[pend], nums[start]
    found = pend - start
    
    if k - found == 0:
        return pend - 1
    elif k > found:
        return kthlargestUtil(nums, k - found, pend, end)
    else:
        return kthlargestUtil(nums, k, start, pend - 1)


test1 = [1, 1, 1, 1, 1]
print kthlargest(test1, 2)

test2 = [3,10,1000,-99,4,100]
print kthlargest(test2, 3)


被坐标搞死了。。
The high lightened cord is due to solve the edge case
1. 全部都是一样的值
2. 选出来的那个pivot正好是左半边的最小值。

Comments

Popular posts from this blog

Unique Binary Search Trees

Longest prefix matching - trie