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

239. 滑动窗口最大值

单调队列

push(): 如果push进来的元素都比前面大,那么前面的元素都要弹出去,直到前面元素没有新加入的元素大为止

pop(): 从出口pop()

getMaxValue(): 返回出口处的值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回 滑动窗口中的最大值 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/sliding-window-maximum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class MyQueue {
    Deque queue = new LinkedList<>();
    // 弹出元素时,比较当前弹出的数值是否等于队列出口的数值如果相等则弹出
    // 为什么要判断是否等于出口的元素呢?
    // 因为不是所有元素都被添加到队列中
    // 同时判断队列元素是否为空
    void poll(int val){
        if(!queue.isEmpty() && val == queue.peek()){
            queue.poll();
        }
    }
    // 添加元素时如果要添加的元素大于入口处元素则删除入口处元素
    void add(int val) {
        while(!queue.isEmpty() && val > queue.getLast()){
            queue.pollLast();
        }
        queue.add(val);
    }
    // 队列出口元素永远为最大值
    int getMaxValue() {
        return queue.peek();
    }
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        // base case
        if(nums.length==1){
            return nums;
        }
        // result 数组
        int [] res = new int [nums.length-k +1];
        int index = 0;
        MyQueue queue = new MyQueue();
        // 先将前k个元素放进队列
        for(int i =0;i

347.前 K 个高频元素

大小堆问题

最大堆/小顶堆:从队头到队尾从小往大排

最小堆/大顶堆:从队头到队尾从大往小排

Comparator: 返回负数,形参中第一个参数在前面;返回正数,形参中第二个参数在前面

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        // 使用map存储元素:key是值,val是出现的频率
        Map map = new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        // 基于大顶堆实现: 大顶堆是从大到小排序
        PriorityQueue pq = new PriorityQueue<>((pair1,pair2)->pair2[1]-pair1[1]);
        // 从map中添加到优先队列中
        for(Map.Entry entry:map.entrySet()){
            pq.add(new int[]{entry.getKey(),entry.getValue()});
        }
        // 最前面的k个元素就是要找的高频元素
        int [] ans = new int[k];
        for(int i=0;i

大顶堆实现:需要 对所有的元素进行排序 最后弹射出前k个元素

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        // 使用map存储元素:key是值,val是出现的频率
        Map map = new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        // 基于小顶堆实现: 大顶堆是从小到大排序
        PriorityQueue pq = new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]);
        // 从map中添加到优先队列中
        for(Map.Entry entry:map.entrySet()){
            // 如果小顶堆的大小小于k直接添加
            if(pq.size()pq.peek()[1]){
                    pq.poll();
                    pq.add(new int[]{entry.getKey(),entry.getValue()});
                }
            }
        }
        // 最前面的k个元素就是要找的高频元素
        int [] ans = new int[k];
        for(int i=0;i

小顶堆实现:只需要对k个元素进行排序,永远维持pq大小为k最后弹射出k个元素

这道题要注意PriorityQueue的一些基本API

你可能感兴趣的:(算法,leetcode,数据结构)