版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012292754/article/details/87351370
1 PriorityQueue
实现方式
1.1 时间复杂度
2 返回数据流中第 K 大元素
https://leetcode.com/problems/kth-largest-element-in-a-stream/
- 最大的值,保存前 K 个,每次来的新的值,只要比保存的 K 个值的最小值大,则剔除原来 K 个值得最小值;
class KthLargest {
private PriorityQueue<Integer> q;
private int k;
public KthLargest(int k, int[] nums) {
this.k = k;
q = new PriorityQueue<>(k);
for (int num : nums) {
add(num);
}
}
public int add(int val) {
if (q.size() < k) {
q.offer(val);
} else if (q.peek() < val) {
q.poll();
q.offer(val);
}
return q.peek();
}
}
3 返回滑动窗口的最大值
- 思路1 :
Max Heap
1. 维护 heap , 时间复杂度 O (logK)
2. 取最大值:时间复杂度 O(1)
3. 总体的时间复杂度: N * log K
- 思路2: 双端队列
时间复杂度:O (N*1)
package heap;
import java.util.ArrayDeque;
import java.util.Deque;
public class SlidWindowMax_239 {
public int[] maxSlidingWindow(int[] nums, int k) {
/*
*
* 判断最大元素是否超出滑动窗口,若超出则将最大元素移除队列
* 可以保证队列内的元素始终小于等于 k 个,这个才是整个算法的关键
* 注意队列里放的是元素的索引,而不是元素的值
* */
if (nums == null || k <= 0) {
return new int[0];
}
int n = nums.length;
int[] r = new int[n - k + 1];
int ri = 0;
//store index
Deque<Integer> q = new ArrayDeque<>(k);
for (int i = 0; i < nums.length; i++) {
// remove numbers out of range k
if (!q.isEmpty() && q.peek() < i - k + 1) {
q.poll();
}
// 新的元素 a[i] 要入队,入队之前要先清除比 a[i] 小的元素
// 新元素进入window要从右侧元素开始比较,不能从左侧比较。
while (!q.isEmpty() && nums[q.peekLast()] <= nums[i]) {
q.pollLast();
}
q.offer(i);
if (i >= k - 1) {
r[ri++] = nums[q.peek()];
}
}
return r;
}
}