#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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

posted @ 2019-11-09 13:40  xyy999  阅读(159)  评论(0)    收藏  举报