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 ...
随机推荐
- Vuex----Getters
Getter 用于对 Store中的数据进行加工处理形成新的数据. Getter 不会修改 Store 中的原数据,它只起到一个包装器的作用,将Store中的数据加工后输出出来. const stor ...
- java-------导出数据csv
outputStream = new FileOutoutStream(file); outputStreamWriter = new OutputStreamWriter (outputStream ...
- C语言初级阶段7——指针2——特殊指针
C语言初级阶段7--指针2--特殊指针 指针函数:是一个函数,返回值类型是一个指针. #include<stdio.h> int* fun() { //a是一个局部变量 int a = 1 ...
- 基于CMMI的软件工程及实训指导 第一章
第一章 软件工程基础 1. 软件工程概述 1.1 软件工程概念 软件工程是从管理和技术两方面来研究如何采用工程的概念.原理和技术方面并加以综合,指导开发人员更好地开发和维护计算机软件的一门新学科. 1 ...
- 通过简单实现一个阻塞队列了解ReentraintLock
MyBlockingQueue 代码 package com.kms.test; import java.util.LinkedList; import java.util.concurrent.lo ...
- SDC细节归纳
能否写出一份严谨的SDC约束文件,决定了芯片tapeout后数字电路能否正常工作,或者少一些bug.所以写好SDC约束文件,是芯片设计的关键一步. 因此,归纳.整理SDC约束的细节要点很重要,有助于减 ...
- 2.IDEA的快捷键
1.IDEA代码等式两边自动加空格:ctrl+alt+L
- switch case return return 返回不了值的原因
我在页面写了一个ajax ,但是控制器 是 用switch case break 控制的控制器 , 我想 在case login 方法里 直接 return , 但是不好使 始终是 null , ...
- ElseViewer--校稿
1Edit ModeThis presents the proof in continuous scroll to review and make corrections. By default, y ...
- 给jui(dwz)的菜单树换一套漂亮的图标
JUI是一个免费开源的框架,在使用初期,会遇到一些麻烦,因为文档实在太少了,完全不知道从哪里入门,但是,一旦你深入学习后,你会发现,你的选择是不错的,它会提高你开发的效率,同时,你会深深爱上它. 目前 ...