第一篇---滑动窗口最大值、前 K 个高频元素
滑动窗口最大值*
题目链接:链接: 239. 滑动窗口最大值
题目:
---给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
1 3 -1\] -3 5 3 6 7 3
1 \[3 -1 -3\] 5 3 6 7 3
1 3 \[-1 -3 5\] 3 6 7 5
1 3 -1 \[-3 5 3\] 6 7 5
1 3 -1 -3 \[5 3 6\] 7 6
1 3 -1 -3 5 \[3 6 7\] 7
### 思路:
首先要知道输出数组的长度为len-k+1,然后写出添加元素和删除元素的两个方法,在初始化窗口之后,之后的每一次循环将队头元素存入res数组直至循环结束。
**添加元素** :每次添加一个元素时,**保证每一次循环后队头元素是最大的!** (在k\>=2,队列中可以出现相同的最大元素)
**删除元素** :在初始化窗口之后,**每一次循环后要保证队列中没有本次窗口之外的元素。**(以示例代码)例如:第一次循环后,保证下标为0的元素(1)不在队列中;第二次循环后,保证下标为1的元素(3)不在队列中
### 代码:
用时32ms,内存57,3MB
```java
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] res = new int[n-k+1];
Deque
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
- 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
- 你的算法的时间复杂度必须优于 O ( n log n ) O(n \log n) O(nlogn) , n 是数组的大小。
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
- 你可以按任意顺序返回答案。
思路:
1、统计元素出现频率。 【使用map来存储数组中每个元素及其出现的频率】
2、对频率进行排序。 【定义一个小顶堆(使用PriorityQueue来实现):从队头到队尾是由小到大排序】
3、找出前k个高频元素。【当添加进优先级队列中的元素(数组)个数大于k时,排出队头元素,剩下的就是频率前k的元素(数组)】
代码:
用时13ms,内存44.3MB
java
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//用map获取数组中每个元素及其对应的频率
Map<Integer,Integer> map = new HashMap<>();
for(int num : nums)
map.put(num,map.getOrDefault(num,0) + 1);
//定义一个堆(lambda 表达式设置优先级队列存储:o1-o2是由小到大,o2-o1是由大到小)
PriorityQueue<int[]> pq = new PriorityQueue<>((o1,o2)->o1[1] - o2[1]);
for(Map.Entry<Integer,Integer> entry: map.entrySet()){
//下面的代码是根据小根堆实现的,我只保留优先队列的最后的k个,只要超出了k我就将最小的弹出,剩余的k个就是答案
pq.offer(new int[]{entry.getKey(),entry.getValue()});
if(pq.size() > k){
pq.poll();
}
}
//获取结果
int[] ans = new int[k];
for(int i = k - 1; i >= 0; i--){
ans[i] = pq.poll()[0];
}
return ans;
}
}