#leetCode刷题纪实 Day11
https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/submissions/
设计一个找到数据流中第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。
小菜鸡的尝试:
因为c++学的不是很好,所以类的编程写得磕磕巴巴的。虽然用了优先队列,但还是超时了,我寻思可能是因为对于每个add操作都是O(n)复杂度的pop()。于是想着,能不能对于每个add操作都是O(1)
1 class KthLargest { 2 public: 3 int k; 4 priority_queue<int> que; 5 KthLargest(int k, vector<int>& nums) { 6 // 构造优先队列 7 priority_queue<int> que; 8 for (int i = 0; i < nums.size(); i ++) { 9 que.push(nums[i]); 10 } 11 // 成员函数setter 12 this -> k = k; 13 this -> que = que; 14 } 15 16 int add(int val) { 17 priority_queue<int> que = this -> que; 18 que.push(val); 19 this -> que = que; 20 priority_queue<int> que0 = que; 21 int k = this -> k; 22 for (int i = 0; i < k - 1; i ++) { 23 que0.pop(); 24 } 25 return que0.top(); 26 } 27 };
优化后的方案:因为要求第K大的数,因此比当前第K大的数小的数是我们不需要考虑的,我们只需要面对比当前第K大的数大的数进行思考即可。
因此:优先队列中不需要存储比当前第K大的数小的数,队列的头就是第K大的数。如果下一个add的数是小于队列头的数,则不需要进行处理,直接返回队头。如果下一个add的数是大于队列的头,则入队,再弹出此时队列的头。返回弹出后队列的头。(至此就是最基本的思路)
当然这样的代码是不健壮的(我怎么知道?因为我不停地在被数据集WA啊)【举个栗子,如果我要求第三大的数,但我初始化的数据只有两个,那么无论此时add的数是大是小,他就应该是第三大的数!awsl】
1 class KthLargest { 2 public: 3 int k; 4 int num; 5 priority_queue<int, vector<int>, greater<>> que; 6 int length; 7 KthLargest(int k, vector<int>& nums) { 8 // 构造优先队列 9 priority_queue<int, vector<int>, greater<>> queue; 10 int num = INT_MAX; 11 if (nums.empty()) { 12 this -> que = queue; 13 this -> num = num; 14 this -> length = 0; 15 this -> k = k; 16 } else { 17 int size = nums.size(); 18 for (int i = 0; i < size; i ++) { 19 queue.push(nums[i]); 20 } 21 for (int i = 0; i < size - k; i ++) { 22 queue.pop(); 23 } 24 int num = queue.top(); 25 // 成员函数 26 this -> num = num; 27 this -> que = queue; 28 this -> length = size; 29 this -> k = k; 30 } 31 } 32 33 int add(int val) { 34 priority_queue<int, vector<int>, greater<>> queue = this -> que; 35 int i = this -> num; 36 int length = this -> length; 37 int k = this -> k; 38 if (i == INT_MAX) { 39 i = val; 40 queue.push(val); 41 this -> que = queue; 42 this -> num = i; 43 this -> length = ++ length; 44 return i; 45 } 46 if (++ length == k) { 47 queue.push(val); 48 this -> que = queue; 49 this -> length = ++ length; 50 return queue.top(); 51 } 52 if (val < i) { 53 this -> length = ++ length; 54 return i; 55 } 56 queue.push(val); 57 queue.pop(); 58 this -> que = queue; 59 this -> num = queue.top(); 60 this -> length = ++ length; 61 return queue.top(); 62 } 63 };
膜拜大佬代码:
一样的思路,但人大佬的代码就!简洁美观!言简意赅!!
1 class KthLargest { 2 public: 3 priority_queue<int, vector<int>, greater<int>> pq; 4 int size; 5 6 KthLargest(int k, vector<int> nums) { 7 size=k;//将小根堆的大小控制在k 8 for(int i=0;i<nums.size();i++) { 9 pq.push(nums[i]); 10 if(pq.size()>k) pq.pop(); 11 } 12 } 13 14 int add(int val) { 15 pq.push(val); 16 if(pq.size()>size) pq.pop(); 17 return pq.top(); 18 } 19 };
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

浙公网安备 33010602011771号