知识点总结
单调队列
使用双端队列
实现单调队列,两个要求
- 放进队列的元素比尾部的元素大
- 头结点在滑动窗口内
优先队列
PriorityQueue
优先队列实现数据结构中大根堆和小根堆。- 常用方法:
add()
:添加元素
peek()
:获取堆顶元素
poll()
:获取堆顶元素,堆顶元素弹出
size()
:获取堆中元素个数
isEmpty()
:判空
PriorityQueue
的使用
- 不用比较器,默认升序排列(堆顶事最小值)
PriorityQueue<Integer, Integer> pq = new PriorityQueue<>();
- 使用比较器,自定义排序方式
//升序排列
PriorityQueue<Integer, Integer> pq = new PriorityQueue<>(new Comparator<>() {
public int compare(Integer e1, Integer e2) {
return e1 - e2;
}
});
//降序排列
PriorityQueue<Integer, Integer> pq = new PriorityQueue<>(new Comparator<>() {
public int compare(Integer e1, Integer e2) {
return e2 - e1;
}
});
//lambda表达式,升序排列
PriorityQueue<Integer, Integer> pq = new PriorityQueue<>((e1, e2) -> e1 - e2);
- 注意点
- poll()、add()方法时间复杂度为
O(log(n))
- 基于优先堆的一个无界队列,这个优先队列中的元素可以
默认自然排序
或者通过提供的Comparator(比较器)
在队列实例化的时排序。优先队列的头
是基于自然排序或者Comparator排序的最小元素
。堆排序只能保证根是最大(最小)
,整个堆并不是有序
的
239. 滑动窗口最大值
代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new LinkedList<>();
int n = nums.length;
int[] res = new int[n - k + 1];
for (int i = 0; i < k; i++) {
while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
deque.pollLast();
}
deque.offerLast(i);
}
res[0] = nums[deque.peekFirst()];
for (int i = k; i < n; i++) {
while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
deque.pollLast();
}
deque.offerLast(i);
if (deque.peekFirst() <= i - k) {
deque.pollFirst();
}
res[i - k + 1] = nums[deque.peekFirst()];
}
return res;
}
}
347.前 K 个高频元素
代码如下:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
//getOrDefault(key, default):获取key的value,如果找不到key,就返回设定的默认值default
map.put(num, map.getOrDefault(num, 0) + 1);
}
System.out.println(map);
//在优先队列中存储二元组[num,cnt],cnt表示元素值num在数组中的出现次数
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2) -> pair1[1] - pair2[1]);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (pq.size() < k) {
pq.add(new int[]{entry.getKey(), entry.getValue()});
} else {
if (entry.getValue() > pq.peek()[1]) {
pq.poll();
pq.add(new int[]{entry.getKey(), entry.getValue()});
}
}
}
int[] res = new int[k];
for (int i = k - 1; i >= 0; i--) {
res[i] = pq.poll()[0];
}
return res;
}
}