代码随想录
239. 滑动窗口最大值
思路
单调队列?
错误代码
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(k == 1) return nums;
int[] res = new int[nums.length-k+1];
Deque<Integer> q = new ArrayDeque<>();
//初始化窗口
for(int i = 0;i<k;i++){
if(q.peekLast()==null){
q.addLast(nums[i]);
}
else if(q.peekLast()!=null && q.peekLast()<nums[i]){
while(q.peekLast()!=null && q.peekLast()<nums[i]){
q.pollLast();
}
q.addLast(nums[i]);
}
}
//
for(int index = k;index<nums.length;index++){
res[k-index] = q.pollFirst();
if(q.peekLast()==null){
q.addLast(nums[index]);
}else if(q.peekLast()!=null && q.peekLast()<nums[index]){
while(q.peekLast()!=null && q.peekLast()<nums[index]){
q.pollLast();
}
q.addLast(nums[index]);
}
}
return res;
}
}
正确代码
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (k == 1)
return nums;
int[] res = new int[nums.length - k + 1];
Deque<Integer> q = new ArrayDeque<>();
// 初始化窗口
for (int i = 0; i < k; i++) {
while (q.peekLast() != null && q.peekLast() < nums[i]) {
q.pollLast();
}
q.addLast(nums[i]);
}
//
for (int index = k; index < nums.length; index++) {
res[index - k] = q.peekFirst();
if (nums[index - k] == res[index - k]) {
q.pollFirst();
}
while (q.peekLast() != null && q.peekLast() < nums[index]) {
q.pollLast();
}
q.addLast(nums[index]);
}
res[nums.length - k] = q.peekFirst();
return res;
}
}
问题分析
建立单调队列,每次都要往队列里面插入当前元素,首先先把队列中小于当前元素的值清空,最后插入。
看了题解以后发现可以先创建一个单调队列的类,可能更好一点?
347.前 K 个高频元素
思路
建立一个哈希表,统计每个元素出现的个数。
题解思路:使用map,key为元素,value为出现频率,对出现频率进行排序。
构建小顶堆,将所有频率放入堆,如果堆的大小大于K,就将元素从堆顶弹出,这样就保留最大的K个高频元素了。
首先考虑的是要统计出现的个数,所以想到哈希表这个结构,然后前k个,可以想到需要对他们进行排序。
小顶堆指的是父元素比孩子元素小,大顶堆指的是父元素比孩子元素大。
可以使用优先队列实现。
题解代码逻辑:
1、先统计好每个元素出现的个数
2、放入优先队列PriorityQueue,小顶堆,队列里的每个元素都是[元素,个数]
3、取出频率出现前k高的元素
代码
class Solution {
public int[] topKFrequent(int[] nums, int k) {
//先统计好每个元素出现的个数
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int num:nums){
map.put(num,map.getOrDefault(num,0)+1);
}
//在优先队列中存储二元组(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{
pq.add(new int[]{entry.getKey(),entry.getValue()});
pq.poll();
}
}
int[] res = new int[k];
for(int i =0;i<k;i++){
res[i] = pq.poll()[0];
}
return res;
}
}