day 13 | 栈与队列part03 239. 滑动窗口最大值 347.前 K 个高频元素

文章介绍了两种算法问题的解决方案:一是使用滑动窗口和双端队列找到数组中每个滑动窗口的最大值;二是利用哈希映射和优先队列找出数组中出现频率最高的前K个元素。这两种方法分别针对数组处理的不同场景,展示了数据结构在算法设计中的应用。
摘要由CSDN通过智能技术生成

239. 滑动窗口最大值

思路: 好难,看了思路也一知半解

class Solution {
        public int[] maxSlidingWindow(int[] nums, int k) {
        // 窗口个数
        int[] res = new int[nums.length - k + 1];
        LinkedList<Integer> queue = new LinkedList<>();

        // 遍历数组中元素,right表示滑动窗口右边界
        for(int right = 0; right < nums.length; right++) {
            // 如果队列不为空且当前考察元素大于等于队尾元素,则将队尾元素移除。
            // 直到,队列为空或当前考察元素小于新的队尾元素
            while (!queue.isEmpty() && nums[right] >= nums[queue.peekLast()]) {
                queue.removeLast();
            }

            // 存储元素下标
            queue.addLast(right);

            // 计算窗口左侧边界
            int left = right - k +1;
            // 当队首元素的下标小于滑动窗口左侧边界left时
            // 表示队首元素已经不再滑动窗口内,因此将其从队首移除
            if (queue.peekFirst() < left) {
                queue.removeFirst();
            }

            // 由于数组下标从0开始,因此当窗口右边界right+1大于等于窗口大小k时
            // 意味着窗口形成。此时,队首元素就是该窗口内的最大值
            if (right +1 >= k) {
                res[left] = nums[queue.peekFirst()];
            }
        }
        return res;
    }

}

347. 前 K 个高频元素

思路:感觉不是很难,主要是coding要好好写

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        //设置一个map集合,key存放数字,value存放出现次数
        Map<Integer,Integer> map = new HashMap<>();
        //统计出现次数
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        //建立一个大根堆,用来存放key值,堆内元素按照key对应的value值从大到小排序
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){
            public int compare(Integer a,Integer b){
                return map.get(a) - map.get(b);
            }
        });
        //将map中的数字,插入到大根堆中
        for(Integer key:map.keySet()){
            if(queue.size() < k){
                queue.add(key);
            }else if(map.get(key) > map.get(queue.peek())){
                queue.poll();
                queue.add(key);
            }
        }
        //将大根堆中的k个数字放到数组中
        int [] res = new int[k];
        int index = 0;
        while(!queue.isEmpty()){
            res[index++] = queue.poll();
        }
        return res;
    }
}
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值