代码随想录算法训练营第十一天|239.滑动窗口最大值、347.前k个高频元素

本文探讨了如何利用队列和大顶堆解决两个经典问题:347.前k个高频元素和239.滑动窗口最大值。通过单调队列实现窗口最大值,利用大顶堆维持高频元素。详细解析了解题思路和示例代码,适合理解数据结构在算法中的实践应用。
摘要由CSDN通过智能技术生成

链接:代码随想录

文章目录  

  • 239.滑动窗口最大值
  • 347.前k个高频元素
  • 解题方法
    • 题目思路
    • 示例代码
  • 总结

解题思路

1.239.滑动窗口最大值 解题思路

因为窗口最前面的元素先进先出,很自然地会用到队列,但还需要排序找出最大值,所以要先采用单调队列,重写一个单调队列,然后储存每一个最大值

代码如下(示例):

 

class MyQueue{
    Deque<Integer> deque = new LinkedList<>();
    void poll(int val) {
        if(!deque.isEmpty() && val==deque.peek()){  //入列判断,相等即弹出
            deque.poll();     
        }
    }
    void add(int val){
        while(!deque.isEmpty() && val > deque.getLast()){    //如果比端口元素则进列
            deque.removeLast();
        }
        deque.add(val);
    }
    int peek(){
        return deque.peek();
    }
}

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int len = nums.length - k + 1;
        int[] res = new int[len];
        int num = 0;
        MyQueue queue = new MyQueue();
        for(int i = 0;i <k;i++){    //储存前k个元素
            queue.add(nums[i]);
        }
        res[num++] = queue.peek();
        for(int i = k;i <nums.length;i++){  
            queue.poll(nums[i-k]);
            queue.add(nums[i]);
            res[num++] = queue.peek();
        }
        return res;
    }
}

2.347.前k个高频元素 解题思路

大顶堆

代码如下(示例):

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        //从大到小排
        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++){
            ans[i] = pq.poll()[0];
        }
        return ans;
    }
}

总结 

关于栈和队列的算法题,需要理解到本身自带方法的构成,并且会修改这些方法,需要牢记先进先出,先进后出的模型与题目内容进行比较,找出适合的模型,对于一些更加复杂的问题,需要细想分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kingsman、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值