第一篇---滑动窗口最大值、前 K 个高频元素

devtools/2024/11/15 0:22:31/

第一篇---滑动窗口最大值、前 K 个高频元素

  • 滑动窗口最大值*
    • 题目:
    • 思路:
    • 代码:
  • 前 K 个高频元素*
    • 题目:
    • 思路:
    • 代码:

滑动窗口最大值*

题目链接:链接: 239. 滑动窗口最大值

题目:

—给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。

示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值


[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

思路:

首先要知道输出数组的长度为len-k+1,然后写出添加元素和删除元素的两个方法,在初始化窗口之后,之后的每一次循环将队头元素存入res数组直至循环结束。
添加元素:每次添加一个元素时,保证每一次循环后队头元素是最大的!(在k>=2,队列中可以出现相同的最大元素)
删除元素:在初始化窗口之后,每一次循环后要保证队列中没有本次窗口之外的元素。(以示例代码)例如:第一次循环后,保证下标为0的元素(1)不在队列中;第二次循环后,保证下标为1的元素(3)不在队列中

代码:

用时32ms,内存57,3MB

java">class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;int[] res = new int[n-k+1];Deque<Integer> queue = new ArrayDeque<>();//窗口初始化for(int i = 0; i < k; i++){Add(queue,nums[i]);}int index = 0;res[index++] = queue.peek();//先进行删除操作,后进行添加for(int i = k; i < n; i++){Delete(queue,nums[i-k]);Add(queue,nums[i]);res[index++] = queue.peek();}return res;}//添加元素:比队尾元素大就排出队尾元素,然后继续与队尾比较,这样就能保证每一次循环后队头元素是最大的!public Deque<Integer> Add(Deque<Integer> queue, int num){while(!queue.isEmpty() && num > queue.peekLast()){queue.pollLast();}queue.offer(num);return queue;}//删除元素:将本次循环要被删除的元素与队头元素比较,若不相等,则表示在进行添加操作时已经排出了前者,直接进行返回就行;若相等,就要排出队头元素再返回public Deque<Integer> Delete(Deque<Integer> queue,int num){if(!queue.isEmpty() && num == queue.peek()){queue.poll();}return queue;}
}

用时41ms,内存58,3MB

java">//自定义数组
class MyQueue {Deque<Integer> deque = new LinkedList<>();void poll(int val) {if (!deque.isEmpty() && val == deque.peek()) {deque.poll();}}//添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出//保证队列元素单调递减//比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2void add(int val) {while (!deque.isEmpty() && val > deque.getLast()) {deque.removeLast();}deque.add(val);}//队列队顶元素始终为最大值int peek() {return deque.peek();}
}class Solution {public int[] maxSlidingWindow(int[] nums, int k) {if (nums.length == 1) {return nums;}int len = nums.length - k + 1;//存放结果元素的数组int[] res = new int[len];int num = 0;//自定义队列MyQueue myQueue = new MyQueue();//先将前k的元素放入队列for (int i = 0; i < k; i++) {myQueue.add(nums[i]);}res[num++] = myQueue.peek();for (int i = k; i < nums.length; i++) {//滑动窗口移除最前面的元素,移除是判断该元素是否放入队列myQueue.poll(nums[i - k]);//滑动窗口加入最后面的元素myQueue.add(nums[i]);//记录对应的最大值res[num++] = myQueue.peek();}return res;}
}

前 K 个高频元素*

题目链接:链接: 347.前 K 个高频元素

题目:

—给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:

输入: nums = [1], k = 1
输出: [1]
提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O ( n log ⁡ n ) O(n \log n) O(nlogn) , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。

思路:

1、统计元素出现频率。【使用map来存储数组中每个元素及其出现的频率】
2、对频率进行排序。【定义一个小顶堆(使用PriorityQueue来实现):从队头到队尾是由小到大排序】
3、找出前k个高频元素。【当添加进优先级队列中的元素(数组)个数大于k时,排出队头元素,剩下的就是频率前k的元素(数组)】

代码:

用时13ms,内存44.3MB

java">class Solution {public int[] topKFrequent(int[] nums, int k) {//用map获取数组中每个元素及其对应的频率Map<Integer,Integer> map = new HashMap<>();for(int num : nums)map.put(num,map.getOrDefault(num,0) + 1);//定义一个堆(lambda 表达式设置优先级队列存储:o1-o2是由小到大,o2-o1是由大到小)PriorityQueue<int[]> pq = new PriorityQueue<>((o1,o2)->o1[1] - o2[1]);for(Map.Entry<Integer,Integer> entry: map.entrySet()){//下面的代码是根据小根堆实现的,我只保留优先队列的最后的k个,只要超出了k我就将最小的弹出,剩余的k个就是答案pq.offer(new int[]{entry.getKey(),entry.getValue()});if(pq.size() > k){pq.poll();}}//获取结果int[] ans = new int[k];for(int i = k - 1; i >= 0; i--){ans[i] = pq.poll()[0];}return ans;}
}

http://www.ppmy.cn/devtools/114291.html

相关文章

vue2基础系列教程之todo的实现及面试高频问题

关键知识点 v2里面&#xff0c;当在同一个元素或组件上同时使用v-for和v-if,v-for的权限高于v-if v-show和v-if的区别主要有 v-if是惰性的&#xff0c;v-show是及时的v-if值为false时&#xff0c;不会生成dom,v-show不管值是true或false,都会生成dom,修改的是dom的display属性…

『功能项目』调整Boss技能bug【51】

我们打开上一篇50切换职业技能面板的项目&#xff0c; 本章要做的事情是调整主角在进入boss01攻击范围内生成的boss技能特效在主角离开时有时会不消失的bug 修改脚本&#xff1a;BossOpt.cs 另外修应该一个冗余脚本&#xff1a;PlayerOpt.cs 运行项目 - 主角在进入boss01攻击范…

深入 mysql,掌握一对一、一对多、多对多表设计、查询及级联操作

数据库表的基本概念与关系 数据库通常包含多个表&#xff0c;每个表存储特定类型的信息。例如&#xff1a; 学生表&#xff1a;存储学生信息。老师表&#xff1a;存储老师信息。班级表&#xff1a;存储班级信息。 这些表通过各种关系连接&#xff0c;形成一个结构化的数据管…

服务器管理:从零开始的服务器安装与配置指南

在现代IT环境中&#xff0c;服务器的安装和配置是每个运维工程师必须掌握的基本技能。本文将详细介绍如何从零开始安装和配置一台服务器&#xff0c;确保内容通俗易懂&#xff0c;并配以代码示例和必要的图片说明。 一、准备工作 在开始安装服务器之前&#xff0c;需要准备以…

网络协议习题第一章

习题 根据IP地址的格式计算,最多有多少个A类、B类和C类网络号 A类网中&#xff0c;网络号占7个bit, 则允许指派的网络数为2^7128&#xff0c;但是要除去0和127的情况&#xff0c;所以能用的最大网络数是126&#xff08;1~ 126&#xff09;。B类网中&#xff0c;网络号占14个b…

《程序猿之设计模式实战 · 池化思想》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【题解】CF2009G1

前言 只会做G1 ,但尽量做到最好&#xff0c;除了一开始的排序的O(nlogn)&#xff0c;后续处理都是O(n)。可能会对G2和G3有一点点用处。 翻译 原题链接CF2009G1 思路 直接处理等差数列不方便&#xff0c;但这个等差数列性质特殊&#xff0c;即公差为1。所以在一个等差数列…

干货:分享6款ai论文写作助手,一键生成原创论文(步骤+工具)

写一篇论文是一个复杂的过程&#xff0c;涉及多个步骤&#xff0c;包括选题、研究、撰写、编辑和校对。AI可以在其中的一些步骤中提供帮助&#xff0c;但最终的论文还是需要人类作者的深入思考和创造性输入。以下是六款值得推荐的AI论文写作助手&#xff0c;其中特别推荐千笔-A…