LeeCode 栈与队列问题(二)
LeeCode 239: 滑动窗口最大值
题目描述
给你一个整数数组
nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。
建立模型
- 单调队列:保存还未被删除的下标, 下标对应的值单调递减
- 对于前
k个数,下标\(0 \le i < j < k\),若 \(nums[i] \ge nums[j]\),则 nums[i]永远不会成为最大值,无需保存 - 对于 [k, nums.length() - 1],循环比较队尾元素和当前元素的大小关系,若当前元素大于等于队尾元素则说明队尾元素永远不会成为最大值,无需保存;
- 然后插入当前元素下标
代码实现
# Python3 实现
def MaxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
# 特殊情况
if k >= len(nums):
return max(nums)
# 使用双端队列保存下标
queue = collections.deque()
# 前 k 个元素
for i in range(k):
while queue and nums[queue[-1]] <= nums[i]:
queue.pop()
queue.append(i)
res = [nums[queue[0]]]
for i in range(k, len(nums)):
while queue and nums[queue[-1]] <= nums[i]:
queue.pop()
queue.append(i)
while queue[0] <= i - k:
queue.popleft()
res.append(nums[queue[0]])
return res
// Java 实现
public int[] maxSlidingWindow(int[] nums, int k) {
if (k >= nums.length) {
// return max(nums);
}
Deque<Integer> deque = new ArrayDeque<>();
for (int i = 0; i < k; i++) {
while(!deque.isEmpty() && nums[deque.getLast()] <= nums[i]) {
deque.removeLast();
}
deque.add(i);
}
int[] res = new int[nums.length - k + 1];
res[0] = nums[deque.getFirst()];
int index = 1;
for (int i = k; i < nums.length; i++) {
while(!deque.isEmpty() && nums[deque.getLast()] <= nums[i]) {
deque.removeLast();
}
deque.add(i);
while (deque.getFirst() <= i - k) {
deque.removeFirst();
}
res[index++] = nums[deque.getFirst()];
}
return res;
}
LeeCode 347: 前 K 个高频元素
题目描述
给你一个整数数组
nums和一个整数k,请你返回其中出现频率前k高的元素。你可以按任意顺序返回答案。
建立模型
这是一个堆的问题,这类问题还有比如前K个高频单词,最小K个数等。
- 遍历数组统计所有出现的数字和频数
- 建立一个存储K个元素的小顶堆(自定义排序规则),每次比较堆顶元素和当前元素
- 若当前元素频数大于堆顶元素,则将堆顶元素弹出,添加当前元素
- 返回堆中的所有元素
代码实现
// Java 实现
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);
}
/**
* 自定义排序规则
* 按照数组第2个元素值从小到大排序
*/
Comparator<int[]> comparator = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// TODO Auto-generated method stub
return o1[1] - o2[1];
}
};
// 小顶堆的实现
PriorityQueue<int[]> queue = new PriorityQueue<>(comparator);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int num = entry.getKey();
int value = entry.getValue();
if (queue.size() < k) {
queue.offer(new int[]{num, value});
}
else {
if (queue.peek()[1] < value) {
queue.poll();
queue.offer(new int[]{num, value});
}
}
}
int[] res = new int[k];
int index = 0;
while (index < k) {
res[index++] = queue.poll()[0];
}
return res;
}
- Python3待更新,需手动实现堆
LeeCode 栈与队列问题(二)的更多相关文章
- 算法与数据结构(二) 栈与队列的线性和链式表示(Swift版)
数据结构中的栈与队列还是经常使用的,栈与队列其实就是线性表的一种应用.因为线性队列分为顺序存储和链式存储,所以栈可以分为链栈和顺序栈,队列也可分为顺序队列和链队列.本篇博客其实就是<数据结构之线 ...
- 剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题
一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如 ...
- leecode刷题(26)-- 用栈实现队列
leecode刷题(26)-- 用栈实现队列 用栈实现队列 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返 ...
- SDUT-2132_数据结构实验之栈与队列二:一般算术表达式转换成后缀式
数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运 ...
- 二、 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)
请指教交流! package com.it.hxs.c01; import java.util.Stack; /* 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek) */ ...
- 剑指Offer面试题:6.用两个栈实现队列
一.题目:用两个栈实现队列 题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 原文是使用 ...
- C实现栈和队列
这两天再学习了数据结构的栈和队列,思想很简单,可能是学习PHP那会没有直接使用栈和队列,写的太少,所以用具体代码实现的时候出现了各种错误,感觉还是C语言功底不行.栈和队列不论在面试中还是笔试中都很重要 ...
- JavaScript中的算法之美——栈、队列、表
序 最近花了比较多的时间来学习前端的知识,在这个期间也看到了很多的优秀的文章,其中Aaron可能在这个算法方面算是我的启蒙,在此衷心感谢Aaron的付出和奉献,同时自己也会坚定的走前人这种无私奉献的分 ...
- Java数据结构和算法之栈与队列
二.栈与队列 1.栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底(Bottom). (2)当表中没有元素时称为 ...
- 栈和队列的面试题Java实现【重要】
栈和队列: 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min ...
随机推荐
- Linux安装ODBC连接SQLServer数据库
操作系统:Centos7.2 1.下载ODBC安装包 unixODBC-2.3.9.tar.gz freetds-1.3.9.tar.gz 下载这两个压缩包的地址:ftp://ftp.freetds. ...
- hdu: Dire Wolf(区间DP)
Problem DescriptionDire wolves, also known as Dark wolves, are extraordinarily large and powerful wo ...
- 【.NET】Swagger 允许接口重名
问题: Swagger Failed to load API definition. 相信用过swagger的小伙伴 一定经历过这样的错误,问题点很简单,是接口重名了. 我百度了一下,找不到答案. 谷 ...
- CF1338E JYPnation
题意:给定一个竞赛图,且其中不包含任意一组三元环 $(a, b, c)$,满足 $a \to d$,$b \to d$,$c \to d$,求每个点两两之间的距离之和(若无法达到即为 $614n$). ...
- 安装SQL Server 2008 R2出现的问题及解决方法(配合Visual Studio )
学校的一个作业需要SQL Server,所以就安装一个,没想到还真是有不少问题 总结:遇到问题,取消安装,完全删除(注册表啥的,小心,细心),重新安装. tips:彻底删除SQL Server应用及组 ...
- day49-数据类型、约束条件
数据类型: 1.整型--默认情况下都是带有符号的, id int(8)-- 如果数字没有超过9位,默认用0填充,如果数字超出8位,有几位存几位 总结:针对整型字段,括号内无需指定宽度,因为它默认的宽度 ...
- 通过Rdp实现连接远程桌面
unit UnitMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...
- 利用网络复制安装额外域控制器、利用介质安装额外域控制器、安装RODC额外域控制器
一.拥有多台域控制器的优势 1.分担用户身份验证的负担,改善用户登录的效率 2.容错功能:若有域控制器故障,此时仍然可以有其他正常的域控制器来继续提供服务,因此对用户的服务并不会停止 二.系统提供两种 ...
- windows下 mstsc 远程Ubuntu 图形界面
安装及设置xrdp ------------------------------------------------------ touch ~/installXrdp.sh cat > ~/ ...
- celery 使用
celery 1.celery介绍 celery能用来做什么: 1.异步任务 2.定时任务 3.延迟任务 1.1 理解celery的运行原理 1.可以不依赖任何服务器 通过自身命令 启动服务 2.ce ...