美文网首页
算法记录 | Day11(栈、队列 03)

算法记录 | Day11(栈、队列 03)

作者: perry_Fan | 来源:发表于2022-11-06 20:09 被阅读0次

    【239. 滑动窗口的最大值】

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

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

    
    

    【347.前 K 个高频元素】

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

    示例 1:
    输入: nums = [1,1,1,2,2,3], k = 2
    输出: [1,2]

    示例 2:
    输入: nums = [1], k = 1
    输出: [1]

    class Solution {
        //解法1:基于大顶堆实现
        public int[] topKFrequent1(int[] nums, int k) {
            Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
            for(int num:nums){
                map.put(num,map.getOrDefault(num,0)+1);
            }
            //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
            //出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆)
            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++){//依次从队头弹出k个,就是出现频率前k高的元素
                ans[i] = pq.poll()[0];
            }
            return ans;
        }
        //解法2:基于小顶堆实现
        public int[] topKFrequent2(int[] nums, int k) {
            Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
            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()){//小顶堆只需要维持k个元素有序
                if(pq.size()<k){//小顶堆元素个数小于k个时直接加
                    pq.add(new int[]{entry.getKey(),entry.getValue()});
                }else{
                    if(entry.getValue()>pq.peek()[1]){//当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个)
                        pq.poll();//弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了
                        pq.add(new int[]{entry.getKey(),entry.getValue()});
                    }
                }
            }
            int[] ans = new int[k];
            for(int i=k-1;i>=0;i--){//依次弹出小顶堆,先弹出的是堆的根,出现次数少,后面弹出的出现次数多
                ans[i] = pq.poll()[0];
            }
            return ans;
        }
    }
    

    相关文章

      网友评论

          本文标题:算法记录 | Day11(栈、队列 03)

          本文链接:https://www.haomeiwen.com/subject/bilitdtx.html