设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。
你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。
题目分析:一脸懵逼,这题读不懂。数据流?数据流!add(),后来明白了,public KthLargest()是构造器,在里面进行初始化,然后呢,add()函数表示后面会新增元素,题目意思就是让我们在add()新增元素之和,如何去寻找第k大元素
public KthLargest(int k, int[] nums) {
}
public int add(int val) {
}
}
/**
* Your KthLargest object will be instantiated and called as such:
* KthLargest obj = new KthLargest(k, nums);
* int param_1 = obj.add(val);
*/
思路:运用优先队列来解决。因为优先级队列默认小顶堆,会自动把值最小的元素排在堆顶。
写法一:构造函数里面,调用add函数,将nums数组里面的元素,通过add函数,去和优先队列周旋,这样既能体现“数据流",也能避免数组为空等情况,是比较好的解决方法。
class KthLargest {
final PriorityQueue<Integer> q;// 设一个队列
final int k;// k不变
public KthLargest(int k, int[] nums) {
this.k = k;//获得k的值
q = new PriorityQueue<>();// 初始化队列,刚开始长度为0
//加入元素
for (int n : nums) {
add(n);
}
}
public int add(int val) {
//如果队列的长度<k,将val添加到队列中
if (q.size() < k) {
q.offer(val);
} else if (q.peek() < val) {
//如果队列的长度>=k
q.poll();
q.offer(val);
}
return q.peek();
}
}
写法二:先在构造函数里面,从数组中选出前k个最大的元素,添加到优先队列里面,然后再去add函数里面,进行比较
class KthLargest {
PriorityQueue<Integer> pQueue;
int k;
public KthLargest(int k, int[] nums) {
this.k = k;
pQueue = new PriorityQueue<>();
for (int i = 0; i < nums.length; i++) {
if (pQueue.size() < k) {
pQueue.add(nums[i]);
} else if (nums[i] > pQueue.peek()) {
pQueue.poll();
pQueue.add(nums[i]);
}
}
}
public int add(int val) {
if (pQueue.size() < k) {
pQueue.add(val);
} else if (pQueue.peek() < val) {
pQueue.poll();
pQueue.add(val);
}
return pQueue.peek();
}
}
写法一比较巧妙,学习学习。
end.