代码随想录算法训练营补打卡 day13|239. 滑动窗口最大值 、347.前 K 个高频元素


代码随想录

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;

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值