JAVA二刷-Day13 | 239. 滑动窗口最大值, 347.前 K 个高频元素

JAVA二刷-Day13 | 239. 滑动窗口最大值, 347.前 K 个高频元素

今天的内容涉及到:
双向队列的定义和库:https://blog.csdn.net/top_code/article/details/8650729

小顶堆优先级队列的库:https://blog.csdn.net/BillieFan/article/details/107578057

滑动窗口最大值

LeetCode题目链接:https://leetcode.cn/problems/sliding-window-maximum/

解题思路

  考虑到时间复杂度的问题,如果使用暴力解法的时间复杂度为 O ( n ∗ k ) O(n*k) O(nk),因此设计一个单调队列,使最大值一直保持在队首。同时,为了避免删去最大值时候,后面的顺序混乱,所以push时候要从尾部进行迭代,保证第二个值是第二大的。因此需要取得队列尾部元素的值,以及对队尾元素进行操作。因此需要双向队列来进行实现。

  代码如下:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> llque = new ArrayDeque<Integer>();
        ArrayList<Integer> result = new ArrayList<Integer>();
        // int pre = 0;

        for (int i = 0; i < k; i++) {
            // if (i == 0) pre = nums[i];  
            while (!llque.isEmpty() && nums[i] > llque.peekLast()) {
                llque.pollLast();
            }
            llque.offerLast(nums[i]);
        }
        result.add(llque.peekFirst());
        for (int i = k; i < nums.length; i++) {
            if (nums[i - k] == llque.peekFirst()) llque.poll();
            while (!llque.isEmpty() && nums[i] > llque.peekLast()) {
                llque.pollLast();
            }
            llque.offerLast(nums[i]);
            result.add(llque.peekFirst());
        }

        return result.stream().mapToInt(x -> x).toArray();
    }
}

前 K 个高频元素

LeetCode题目链接:https://leetcode.cn/problems/top-k-frequent-elements/

解题思路

  主要在于掌握优先级队列,大小堆的概念,堆就是填满元素的完全二叉树。因为是要计算高频元素,因此在保存时不仅要保存元素的值,也应当保存元素出现的频次。因此使用map中的entry方法来进行遍历循环。并依靠数组的形式进行存储。

  应当注意的是,在优先级队列中进行排序时,排序的顺序和仿函数中展示的顺序是相反的。同时,由于队列的FIFO原则,应该将小的放在队首用来pop。因此应该用小顶堆。

  具体代码如下:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        PriorityQueue<int[]> pque = new PriorityQueue<>(new Comparator<int[]>() {
            public int compare(int[] e1, int[] e2) {
                //比较方法,此时为小顶堆,堆顶为最小元素。其中第二个为已经在堆中元素,第一个为新元素。
                return e1[1] - e2[1];
            }
        });

        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }

        for (Map.Entry<Integer, Integer> entry: map.entrySet()) {
            if (pque.size() < k) {
                pque.offer(new int[]{entry.getKey(), entry.getValue()});
            }else if (pque.peek()[1] < entry.getValue()){
                pque.poll();
                pque.offer(new int[]{entry.getKey(), entry.getValue()});
            } 
        }
        int[] result = new int[k];
        for (int i = 0; i < k; i++) {
            result[i] = pque.poll()[0];
        }
        return result;
    }
}

你可能感兴趣的:(数据结构,java,开发语言)