1. 程式人生 > >leetcode 703. 資料流中的第K大元素(python)

leetcode 703. 資料流中的第K大元素(python)

設計一個找到資料流中第K大元素的類(class)。注意是排序後的第K大元素,不是第K個不同的元素。

你的 KthLargest 類需要一個同時接收整數 k 和整數陣列nums 的構造器,它包含資料流中的初始元素。每次呼叫 KthLargest.add,返回當前資料流中第K大的元素。

示例:

int k = 3;
int[] arr = [4,5,8,2];
KthLargest kthLargest = new KthLargest(3, arr);
kthLargest.add(3);   // returns 4
kthLargest.add(5);   // returns 5
kthLargest.add(10);  // returns 5
kthLargest.add(9);   // returns 8
kthLargest.add(4);   // returns 8

說明: 
你可以假設 nums 的長度≥ k-1 且k ≥ 1。


class KthLargest(object):

    def __init__(self, k, nums):
        """
        :type k: int
        :type nums: List[int]
        """
        self.pool = nums
        self.size = len(self.pool)
        self.k = k
        #heapq.heapify()將列表原地轉換為堆並排序
        heapq.heapify(self.pool)
        while self.size > k:
            heapq.heappop(self.pool)
            self.size -= 1

    def add(self, val):
        """
        :type val: int
        :rtype: int
        """
        if self.size < self.k:
            heapq.heappush(self.pool, val)
            self.size += 1
        elif val > self.pool[0]:
            heapq.heapreplace(self.pool, val)
        return self.pool[0]


# Your KthLargest object will be instantiated and called as such:
# obj = KthLargest(k, nums)
# param_1 = obj.add(val)

 知識點:heapq--堆佇列

'''
本模組實現了堆佇列演算法,也叫作優先順序佇列演算法。堆佇列是一棵二叉樹,並且擁有這樣特點,它的父節點的值小於等於任何它的子節點的值,如果採用陣列array實現,可以把它們的關係表示為:heap[k] <= heap[2*k+1] 和 heap[k] <= heap[2*k+2],對於所有k值都成立,k值從0開始計算。作為比較,可以認為不存的元素是無窮大的。堆佇列有一個比較重要的特性,它的最小值的元素就是在根:heap[0]。 下面的API與教科書上堆演算法有兩點差別:(a)使用0開始的索引。這樣可能會讓大家看到節點層次的索引上有點彆扭的,但這樣更適合python語言處理,因為python是以0為開始計算陣列和列表的索引。(b)彈出的方法返回的值是最小值,而不是最大值(在教科書上叫作最小堆,最大堆在教科書更通用地使用來教學,因為它更適合排序演算法)。基於上面兩點可以檢視一個堆:heap[0]返回一個最小值的項,heap.sort()對整個堆進行排序。

#建立一個堆佇列,可以使用一個列表[],也可以使用heapify(x)函式。
#heapq.heappush(heap, item) 
#把一項值壓入堆heap,同時維持堆的排序要求。
'''
#例子:
#python 3.4
import heapq 
h = []
heapq.heappush(h, 5)
heapq.heappush(h, 2)
heapq.heappush(h, 8)
heapq.heappush(h, 4)
print(heapq.heappop(h))
#結果輸出如下:
2
--------------------------------------------------------------------------------
#heapq.heappop(heap) 
#彈出並返回堆裡最小值的項,調整堆排序。如果堆為空,丟擲異常IndexError。
#例子:
#python 3.4
import heapq 
h = []
heapq.heappush(h, 5)
heapq.heappush(h, 2)
heapq.heappush(h, 8)
heapq.heappush(h, 4)
print(heapq.heappop(h))
print(heapq.heappop(h))
#結果輸出如下:
2

4
--------------------------------------------------------------------------------------
#heapq.heappushpop(heap, item)
#向堆裡插入一項,並返回最小值的項。組合了前面兩個函式,這樣更加有效率。
#例子:
#python 3.4
import heapq 
h = []
heapq.heappush(h, 5)
heapq.heappush(h, 2)
heapq.heappush(h, 8)
print(heapq.heappushpop(h, 4))
#結果輸出如下:
2
--------------------------------------------------------------------------------------
#heapq.heapify(x) 
#就地轉換一個列表為堆排序,時間為線性。
#例子:
#python 3.4
import heapq
h = [9, 8, 7, 6, 2, 4, 5]
heapq.heapify(h)
print(h)
#結果輸出如下:
[2, 6, 4, 9, 8, 7, 5]
------------------------------------------------------------------------------------
#heapq.heapreplace(heap, item) 
#彈出最小值的項,並返回相應的值,最後把新項壓入堆。如果堆為空丟擲異常IndexError。
#例子:
#python 3.4
import heapq
h = [9, 8, 7, 6, 2, 4, 5]
heapq.heapify(h)
print(h)
print(heapq.heapreplace(h, 1))
print(h)
#結果輸出如下:
[2, 6, 4, 9, 8, 7, 5]
2
[1, 6, 4, 9, 8, 7, 5]
-------------------------------------------------------------------------------------
#heapq.merge(*iterables)
#合併多個堆排序後的列表,返回一個迭代器訪問所有值。
#例子:
#python 3.4
import heapq 
h = [9, 8, 7, 6, 2, 4, 5]
heapq.heapify(h)
l = [19, 11, 3, 15, 16]
heapq.heapify(l)
for i in heapq.merge(h,l):
    print(i, end = ',')
#結果輸出如下:
2,3,6,4,9,8,7,5,11,19,15,16,
---------------------------------------------------------------------------------------
#heapq.nlargest(n, iterable, key=None) 
#從資料集iterable裡獲取n項最大值,以列表方式返回。如果引數 key提供,key是一個比較函式,用來比較元素之間的值。
#例子:
#python 3.4
import heapq
h = [9, 1, 7, 6, 2, 4, 5]
l = heapq.nlargest(3, h)
print(l)
#結果輸出如下:
[9, 7, 6]
---------------------------------------------------------------------------------------
#heapq.nsmallest(n, iterable, key=None) 
#從資料集iterable裡獲取n項最小值,以列表方式返回。如果引數 key提供,key是一個比較函式,用來比較元素之間的值。相當於:sorted(iterable, key=key)[:n]
#例子:
#python 3.4
import heapq
h = [9, 1, 7, 6, 2, 4, 5]
l = heapq.nsmallest(3, h)
print(l)
#結果輸出如下:
[1, 2, 4]
#在最後這兩個函式中,如果數量比較少時使用起來比較高效,如果資料量比較大,要使用sorted()函式,如果n=1最好使用內建函式min()或max()。
---------------------------------------------------------------------------------------
#採用堆演算法來實現排序:
#例子:
#python 3.4
import heapq
def heapsort(iterable):
    '實現與sorted(iterable)相同的功能'
    h = []
    for value in iterable:
        heapq.heappush(h, value)
    return [heapq.heappop(h) for i in range(len(h))]

print(heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]))

#結果輸出如下:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]