Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Your KthLargest
class will have a constructor which accepts an integer k
and an integer array nums
, which contains initial elements from the stream. For each call to the method KthLargest.add
, return the element representing the kth largest element in the stream.
Example:
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
Note:
You may assume that nums
' length ≥ k-1
and k
≥ 1.
這道題讓我們在數據流中求第K大的元素,跟之前那道Kth Largest Element in an Array很類似,但不同的是,那道題的數組是確定的,不會再增加元素,這樣確定第K大的數字就比較簡單。而這道題的數組是不斷在變大的,所以每次第K大的數字都在不停的變化。那么我們其實只關心前K大個數字就可以了,所以我們可以使用一個最小堆來保存前K個數字,當再加入新數字后,最小堆會自動排序,然后把排序后的最小的那個數字去除,則堆中還是K個數字,返回的時候只需返回堆頂元素即可,參見代碼如下:
解法一:
class KthLargest { public: KthLargest(int k, vector<int> nums) { for (int num : nums) { q.push(num); if (q.size() > k) q.pop(); } K = k; } int add(int val) { q.push(val); if (q.size() > K) q.pop(); return q.top(); } private: priority_queue<int, vector<int>, greater<int>> q; int K; };
我們也可以使用multiset來做,利用其可重復,且自動排序的功能,這樣也可以達到最小堆的效果,參見代碼如下:
解法二:
class KthLargest { public: KthLargest(int k, vector<int> nums) { for (int num : nums) { st.insert(num); if (st.size() > k) st.erase(st.begin()); } K = k; } int add(int val) { st.insert(val); if (st.size() > K) st.erase(st.begin()); return *st.begin(); } private: multiset<int> st; int K; };
類似題目:
Kth Largest Element in an Array
參考資料:
https://leetcode.com/problems/kth-largest-element-in-a-stream