//利用双端队列手动实现单调队列
/**
* 用一个单调队列来存储对应的下标,每当窗口滑动的时候,直接取队列的头部指针对应的值放入结果集即可
* 单调队列类似 (tail -->) 3 --> 2 --> 1 --> 0 (--> head) (右边为头结点,元素存的是下标)
*/
class Solution { public int[] maxSlidingWindow(int[] nums, int k) { ArrayDeque<Integer> deque = new ArrayDeque<>(); int n = nums.length; int[] res = new int[n - k + 1]; int idx = 0; for(int i = 0; i < n; i ++){ while(!deque.isEmpty() && deque.peek() < i - k + 1){ deque.poll(); } while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]){ deque.pollLast(); } deque.offer(i); if(i >= k - 1){ res[idx ++] = nums[deque.peek()]; } } return res; } }
class Solution { public int[] topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for(int num : nums){ map.put(num, map.getOrDefault(num, 0) + 1); } 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; } }