package LeetCode.StackAndQueuepart03; import java.util.ArrayDeque; /** * 239. 滑动窗口最大值 * 给你一个整数数组 nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。 * 你只可以看到在滑动窗口内的 k个数字。滑动窗口每次只向右移动一位。 * 返回 滑动窗口中的最大值 。 * 示例: * 输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 * 输出:[3,3,5,5,6,7] * */ public class SlidingWindowMaximum_239 { public static void main(String[] args) { int [] nums = {1,3,-1,-3,5,3,6,7}; int k = 3; int [] result = maxSlidingWindow(nums,k); for (int i = 0; i < result.length; i++) { System.out.print(result[i]+" "); } } public static 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++) { // 根据题意,i为nums下标,是要在[i - k + 1, i] 中选到最大值,只需要保证两点 // 1.队列头结点需要在[i - k + 1, i]范围内,不符合则要弹出 while(!deque.isEmpty() && deque.peek() < i - k + 1){ deque.poll(); } // 2.既然是单调,就要保证每次放进去的数字要比末尾的都大,否则也弹出 while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { deque.pollLast(); } deque.offer(i); // 因为单调,当i增长到符合第一个k范围的时候,每滑动一步都将队列头节点放入结果就行了 if(i >= k - 1){ res[idx++] = nums[deque.peek()]; } } return res; } }
package LeetCode.StackAndQueuepart03; import java.util.HashMap; import java.util.Map; import java.util.PriorityQueue; /** * 347. 前 K 个高频元素 * 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 * 示例: * 输入: nums = [1,1,1,2,2,3], k = 2 * 输出: [1,2] * */ public class TopKFrequentElements_347 { public static int[] topKFrequent2(int[] nums, int k) { Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数 for(int num:nums){ map.put(num,map.getOrDefault(num,0)+1); } //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数 //出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(相当于小顶堆) PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair1[1]-pair2[1]); for(Map.Entry<Integer,Integer> entry:map.entrySet()){//小顶堆只需要维持k个元素有序 if(pq.size()<k){//小顶堆元素个数小于k个时直接加 pq.add(new int[]{entry.getKey(),entry.getValue()}); }else{ if(entry.getValue()>pq.peek()[1]){//当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个) pq.poll();//弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了 pq.add(new int[]{entry.getKey(),entry.getValue()}); } } } int[] ans = new int[k]; for(int i=k-1;i>=0;i--){//依次弹出小顶堆,先弹出的是堆的根,出现次数少,后面弹出的出现次数多 ans[i] = pq.poll()[0]; } return ans; } }
标签:deque,pq,nums,int,part03,次数,347,239,new From: https://www.cnblogs.com/lipinbigdata/p/17389589.html