代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素
基础知识
ArrayDeque deque = new ArrayDeque();
/*
offerFirst(E e) 在数组前面添加元素,并返回是否添加成功
offerLast(E e) 在数组后天添加元素,并返回是否添加成功
pollFirst()删除第一个元素,并返回删除元素的值,如果元素为null,将返回null
pollLast()删除最后一个元素,并返回删除元素的值,如果为null,将返回null
getFirst() 获取第一个元素,如果没有将抛出异常
getLast() 获取最后一个元素,如果没有将抛出异常
toArray() 转成数组
contains(Object o) 判断队列中是否存在该元素
size() 获取队列中元素个数
isEmpty() 判断队列是否为空
队列操作 offer poll peek
栈操作 push pop peek
*/
PriorityQueue
PriorityQueue<Object> pq = new PriorityQueue<>((o1, o2)->o1.xxx-o1.xxx);
// offer poll size toArray contains peek
// Map遍历 效率更高
for (Map.Entry<String, String> entry : myMap.entrySet()) {
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
LeetCode 239. 滑动窗口最大值
分析1.0
遍历数组添加新元素时,要维护一个队列,保证队列元素递减-单调递减队列
失误
不要想着把窗口中的元素全部放进队列再去找最大值
分析2.0
- 首先要将前k个元素按照push原则入队,之后取队首元素
- pop(value):如果窗口移除的元素value等于单调队列的出口元素(使用索引),那么队列弹出元素,否则不用任何操作
- push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
这个要在容器的两头操作,没搞清楚数据结构,用普通队列操作实在是...欲哭无泪,内心愤怒值+++++++++
class Solution {
ArrayDeque<Integer> queue = new ArrayDeque();
public int[] maxSlidingWindow(int[] nums, int k) {
int len = nums.length - k + 1;
int[] res = new int[len];
for(int i = 0; i < k; i++){
// queue不为空 而且首元素小于当前元素时
while(!queue.isEmpty() && nums[queue.peek()] <= nums[i]){
queue.poll();
}
while(!queue.isEmpty() && nums[queue.getLast()] <= nums[i]){
queue.pollLast();
}
queue.offer(i);
}// 前k个元素索引入队
// 后nums.length - k 个元素入队
int inIndex = k, outIndex = 0, index = 0;
res[index++] = nums[queue.peek()];
while(index < len){
addElem(nums, inIndex++, outIndex++);
res[index++] = nums[queue.peek()];
}
return res;
}
public void addElem(int[] nums, int inIndex, int outIndex){
// 要出栈的元素是队首元素的话-通过数组索引锁定
if(!queue.isEmpty() && queue.peek() == outIndex){
queue.poll();
}
while(!queue.isEmpty() && nums[queue.getLast()] <= nums[inIndex]){
queue.pollLast();
}
queue.offer(inIndex);
}
}
LeetCode 347.前 K 个高频元素
分析1.0
Map<元素value,出现频率> ,按照频率降序排序,输出前k个key 或者是在每次遍历数组修改map时,维护map顺序,
维护Map顺序考虑工具 堆 或者 自己实现算法
class Solution {
//解法1:基于大顶堆实现
public int[] topKFrequent(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)->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;
}
}
总结
- 在进行栈、队列等容器操作时,要先判断容器是否为空
- 循环首先要确认终止条件、避免常见的ArrayOutOfIndex错误
- PriorityQueue 实现自定义比较器,构造器参数不能为Map
常用变量名增量更新
size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch
代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素的更多相关文章
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- Java实现 LeetCode 347 前 K 个高频元素
347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...
- Java实现 LeetCode 239 滑动窗口最大值
239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最 ...
- Leetcode 239.滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...
- [LeetCode]347. 前 K 个高频元素(堆)
题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1 ...
- Leetcode 347.前K个高频元素 By Python
给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...
- leetcode 347. 前 K 个高频元素
问题描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...
- leetcode.排序.347前k个高频元素-Java
1. 具体题目 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...
- leetcode 239. 滑动窗口最大值(python)
1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...
- 【leetcode 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
随机推荐
- 基于Nginx搭建WebDAV服务
title: 基于Nginx搭建WebDAV服务 categories: - [IT,网络,服务] tags: - WebDAV - Nginx comments: true date: 2022-1 ...
- docker-compose + mysql8.x 主从数据库配置
0.准备 (略过docker的安装与镜像拉取) docker / docker-compose 安装 拉取 mysql 8.x 1. master和slave的mysql配置 master: [mys ...
- Python中open()文件操作/OS目录操作
File对象测试数据的读写与操作 #def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, ...
- uniapp开发微信小程序
uni-app介绍(官网) uni-app是一个使用Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.H5.以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉 ...
- 掌握webpack(一)一张图让你明白webpack中output的filename、path、publicPath与主流插件的关系
webpack的核心概念,放到2022年相信很多的小伙伴都已经非常清楚了.但是,对于webpack配置中的output.path.output.filename以及output.publicPath, ...
- Redis-03 Redis事务
需要特别注意,Redis 的命令是原子性的,而 Redis 的事务是非原子性的 事务相关命令 MULTI 命令 开启事务命令,Redis将操作命令逐个放到队列中,根据EXEC命令来原子化执行命令 EX ...
- Angularjs——初识AngularJS
AngularJS--初识AngularJS AngularJS是什么 AngularJS是Google开源的一款前端JS结构化框架,它通过对前端开发进行分层,极好地规范了前端开发的风格--它将前端开 ...
- 洛谷 P2440木材加工 题解
这是一道二分答案算法题,洛谷标签中的贪心等完全用不到. 这道题的数据范围较大,所以保险起见,整型的数据我们都开成longlong 题意很好理解,这里就不做过多的分析了,直接看代码,后面有注释: #in ...
- BUG日记--——Linux安装Docker
1.yum makecache fast不适合Centos8 2.解决办法 3.doucke的使用 1.关闭防火墙 # 关闭 systemctl stop firewalld # 禁止开机启动防火墙 ...
- Java 进阶P-4.2+P-4.3
继承 什么是继承:通俗易懂就好像是你继承你了爸的财产,其中你是子类,你爸是父类继承在Java中被称为面向对象的三大的特征,其中他表示的是,从已有的类中派生出新的类,新的类拥有了父类中属性和方法(pri ...