代码随想录-2023/07/10

90 阅读1分钟

栈与队列的应用

239.滑动窗口的最大值

  1. 使用单调队列模拟滑动窗口, 始终保证窗口内元素个数为k个, 且元素为单调递减
  2. 当遍历到k之后, 每次处理一个元素就从队列头出队一个元素, 即为该区间的最大值

代码:

class Solution {
    // 固定滑动窗口大小---求滑动窗口的最大值, 最小值, 中位数
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        int[] ans = new int[n-k+1];
        // 单调队列---单调递减队列
        // 队列中装的是数组元素下标
        int idx = 0;
        Deque<Integer> deque = new ArrayDeque<>();
        for(int i=0; i < nums.length; i++){
            
            // 1.维护队列内部元素的个数 <= k, 队列头元素下标<i-k+1
            while(!deque.isEmpty() && deque.peekFirst() < i-k+1){
                deque.pollFirst();
            }

            // 2.保证单调递减
            while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]){
                deque.pollLast();
            }

            // 3.存入元素
            deque.offerLast(i);

            
            if(i >= k-1) ans[idx++] = nums[deque.peekFirst()];
        }

        return ans;
    }       
}

347.前k个高频元素

基于小顶堆实现:

  1. 先用哈希表统计每个元素的数量
  2. 构造k个元素的小顶堆
  3. 遍历哈希表, 若索引小于k, 直接入队
  4. 当索引大于k, 判断其与堆顶元素大小, 若比堆顶元素大, 则入队; 比堆顶元素还小, 则不入队
  5. 最后遍历完成, 小顶堆内剩下的就是前k个最高频的元素

代码:

class Solution {
    // 基于小顶堆: 时间复杂度 O(nlogk)
    public int[] topKFrequent(int[] nums, int k) {
        int[] ans = new int[k];

        // 1.用哈希表统计元素个数
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<nums.length; i++){
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }

        // 2.构造一个 k 个元素的小顶堆---默认就是小顶堆
        PriorityQueue<int[]> queue = new PriorityQueue<>((c1,c2)->c1[1]-c2[1]);
        int index = 0;
        for(int num : map.keySet()){
            if(index++ < k) {
                queue.offer(new int[]{num, map.get(num)});
            }else{
                if(map.get(num) > queue.peek()[1]){
                    queue.poll();
                    queue.offer(new int[]{num, map.get(num)});
                }
            }

        }
        // 3. 输出答案
        for(int i=0; i<k; i++){
            ans[i] = queue.poll()[0];
        }

        return ans;
    }
}