239. 滑动窗口最大值
239. 滑动窗口最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
//滑动窗口poll、add、peek
if(nums.length == 1){
return nums;
}
int len = nums.length - k + 1;
//创建一个用来存放结果的数组
int []res = new int[len];
int num = 0;
MyQueue myQueue = new MyQueue();
//先将前k个元素放入队列中
for(int i = 0 ; i < k; i++){
myQueue.add(nums[i]);
}
res[num++] = myQueue.peek();
for(int i = k; i <nums.length;i++){
//滑动窗口移除最前面的元素,移除是判断该元素是否放入队列
myQueue.poll(nums[i-k]);
myQueue.add(nums[i]);
res[num++] = myQueue.peek();
}
return res;
}
class MyQueue{
//自定义一个单调队列来解决这个问题:
//采用deque数据结构
Deque<Integer> deque = new LinkedList<>();
void poll(int val){
if(!deque.isEmpty() && val == deque.peek()){ //注意,这里是if
deque.poll();
}
}
void add( int val){
//将比val元素值还要大的前面的而所有元素都移除掉
while(!deque.isEmpty() && val > deque.getLast()){
deque.removeLast();
}
deque.add(val);
}
int peek(){
return deque.peek();
}
}
}
347. 前 K 个高频元素
347. 前 K 个高频元素
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//本题中涉及到元素出现的次数,出现元素次数的排序 考虑用map和大顶堆的思路(优先级队列本质上使用堆来实现的)
Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
for(int num:nums){
map.put(num,map.getOrDefault(num,0)+1);
}
//在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
//出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆)
PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair2[1]-pair1[1]);
for(Map.Entry<Integer,Integer> entry:map.entrySet()){//大顶堆需要对所有元素进行排序
pq.add(new int[]{entry.getKey(),entry.getValue()});
}
int[] ans = new int[k];
for(int i=0;i<k;i++){//依次从队头弹出k个,就是出现频率前k高的元素
ans[i] = pq.poll()[0];
}
return ans;
}
}