算法修炼Day13|● 239. 滑动窗口最大值 ● 347.前 K 个高频元素

86 阅读1分钟
题目:239. 滑动窗口最大值 - 力扣(LeetCode)
思路/想法:

使用双端队列实现,维持队列的元素内容是单调递减的状态,这样能将较大的值保留在队列中。

代码实现:
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int[] ans = new int[nums.length - k + 1];
        Deque<Integer> deque = new ArrayDeque<>();
        int idx = 0;
        for (int i = 0; i < nums.length; i++) {
            // 理想情况下,队列中存储当前范围下的最大元素!!
            while (!deque.isEmpty() && deque.peek() < i - k + 1) { // deque.peekFirst()方法返回deque的第一个元素,如果deque为空则返回null。而null值没法和数值型数字做比较。
                deque.poll();
            }
            while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
                deque.pollLast();
            }
            deque.add(i);
            if (i - k + 1 >= 0) {
                ans[idx++] = nums[deque.peekFirst()];
            }
        }
        return ans;
    }
}
题目:347. 前 K 个高频元素 - 力扣(LeetCode)
思路/想法:

为了更好的干饭,答案抄了好几遍了...

代码实现:
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);
        int[] ans = new int[k];
        Map<Integer, Integer> map = new HashMap<>(); // 记录元素出现的次数
        for (int num : nums) map.put(num, map.getOrDefault(num, 0) + 1);
        for (var x : map.entrySet()) {
            int[] tmp = new int[2];
            tmp[0] = x.getKey();
            tmp[1] = x.getValue();
            pq.add(tmp);
            if (pq.size() > k) {
                pq.poll();
            }
        }
        for (int i = 0; i < k; i++) {
            ans[i] = pq.poll()[0];
        }
        return ans;
    }
}