KOKO-代码随想录算法训练营Day13 | 239|347 |
一、239. 滑动窗口最大值
1.题目
https://leetcode.cn/problems/sliding-window-maximum/
2.代码
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res=new int[nums.length-k+1]; //最终数组的长度
int index=0;
Deque<Integer> que=new ArrayDeque<>();
for (int i = 0; i < nums.length; i++) {
// 模拟滑动窗口的过程,弹出一个,压进来一个,如果队头是和nums[i]一样,队头就该被弹出,不一样,说明曾经的队头被弹出过了
if(i>k-1&&que.peek()==nums[i-k]){
que.poll(); //1,-3,-1,3
}
while (!que.isEmpty()&&nums[i]>que.peekLast()){
que.pollLast();//添加进来的元素比上一个大,则将其之前的元素从后面都出
}
que.offer(nums[i]);//加入从队头加入
if(i>=k-1){
res[index++]=que.peek();
}
}
return res;
}
3.总结
这个题很有意思,最重要的是要知道什么时候从队列头部把元素移出去,模拟出一个,进一个的窗口过程。
在队列保证队头元素是最大的,其他元素没有current元素大时,应该从队尾弹出。
在将current元素压入,
只有在i>k-1时,才进行弹出队头操作,比较的是nums[i-k]和队头元素的大小。
该题不进行优先级队列:
滑动窗口是移动的,队头的元素是要弹出的,大顶堆只能弹出最大值的元素。
二、 347.前 K 个高频元素
1.题目
https://leetcode.cn/problems/top-k-frequent-elements/
2.代码
Map<Integer,Integer> map=new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i],map.getOrDefault(nums[i],0)+1);//频率的统计
}
//定义小顶堆
PriorityQueue<int[]> priorityQueue=new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1]-o2[1];//按频率排大小
}
});
for (Map.Entry<Integer,Integer> entry:map.entrySet()) {
if(priorityQueue.size()<k){
priorityQueue.add(new int[]{entry.getKey(),entry.getValue()});
}else {
if(entry.getValue()>priorityQueue.peek()[1]){
priorityQueue.poll();//如果后面有元素比堆大,则放到小顶堆里作为替换
priorityQueue.add(new int[]{entry.getKey(),entry.getValue()});//只存了前k个
}
}
}
int[] res=new int[k];
for (int i = 0; i < k; i++) {
res[i]=priorityQueue.poll()[0];
}
return res;
3.总结
使用优先级队列,小顶堆,来保存前k个高频词汇,一旦发现有频率比队列头部大时,应将小的弹出,在压入当前值,保持小队顶一直是前k个高频词汇,这样只用比前k个即可。
令,注意小顶堆的排序,
PriorityQueue<int[]> priorityQueue=new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1]-o2[1];//按频率排大小
}
});
Map排序使用List把map.entrySet装进去后用Collections进行排序
List<Map.Entry<Integer,Integer>> list=new ArrayList<>(map.entrySet());//entryset转成list,用Collection比较大小
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
return o2.getValue()-o1.getValue();
}
});