LeeCode 239: 滑动窗口最大值

题目描述

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

建立模型

  1. 单调队列:保存还未被删除的下标, 下标对应的值单调递减
  2. 对于前 k 个数,下标\(0 \le i < j < k\),若 \(nums[i] \ge nums[j]\),则 nums[i]永远不会成为最大值,无需保存
  3. 对于 [k, nums.length() - 1],循环比较队尾元素和当前元素的大小关系,若当前元素大于等于队尾元素则说明队尾元素永远不会成为最大值,无需保存;
  4. 然后插入当前元素下标

代码实现

# 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个数等。

  1. 遍历数组统计所有出现的数字和频数
  2. 建立一个存储K个元素的小顶堆(自定义排序规则),每次比较堆顶元素和当前元素
  3. 若当前元素频数大于堆顶元素,则将堆顶元素弹出,添加当前元素
  4. 返回堆中的所有元素

代码实现

// 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 栈与队列问题(二)的更多相关文章

  1. 算法与数据结构(二) 栈与队列的线性和链式表示(Swift版)

    数据结构中的栈与队列还是经常使用的,栈与队列其实就是线性表的一种应用.因为线性队列分为顺序存储和链式存储,所以栈可以分为链栈和顺序栈,队列也可分为顺序队列和链队列.本篇博客其实就是<数据结构之线 ...

  2. 剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题

    一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如 ...

  3. leecode刷题(26)-- 用栈实现队列

    leecode刷题(26)-- 用栈实现队列 用栈实现队列 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返 ...

  4. SDUT-2132_数据结构实验之栈与队列二:一般算术表达式转换成后缀式

    数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运 ...

  5. 二、 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)

    请指教交流! package com.it.hxs.c01; import java.util.Stack; /* 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek) */ ...

  6. 剑指Offer面试题:6.用两个栈实现队列

    一.题目:用两个栈实现队列 题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 原文是使用 ...

  7. C实现栈和队列

    这两天再学习了数据结构的栈和队列,思想很简单,可能是学习PHP那会没有直接使用栈和队列,写的太少,所以用具体代码实现的时候出现了各种错误,感觉还是C语言功底不行.栈和队列不论在面试中还是笔试中都很重要 ...

  8. JavaScript中的算法之美——栈、队列、表

    序 最近花了比较多的时间来学习前端的知识,在这个期间也看到了很多的优秀的文章,其中Aaron可能在这个算法方面算是我的启蒙,在此衷心感谢Aaron的付出和奉献,同时自己也会坚定的走前人这种无私奉献的分 ...

  9. Java数据结构和算法之栈与队列

    二.栈与队列 1.栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底(Bottom). (2)当表中没有元素时称为 ...

  10. 栈和队列的面试题Java实现【重要】

    栈和队列: 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min ...

随机推荐

  1. Vuex----Mutations

    注意: 只能通过 mutations里的函数才能修改 state 中的数据 第一种方法: const store = new Vuex.Store({ state:{ count:0 }, mutat ...

  2. Thread的状态变更

    [需注意的是:运行中(Running)和就绪(Ready)并不是 Java 的线程状态] public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TI ...

  3. linux基础命令4

    用户和组群账户管理 用户的 角色是通过UID(用户ID号)来标识的,每个用户的UID都是不同的. 在Linux系统中有三大类用户,分别是root 用户.系统用户和普通用户. root用户UID为0.r ...

  4. 打开CMD的方式

    打开Cmd的方式: 1.开始+系统+命令提示符 2.Win键+R 3.在任意文件夹下,按住Shift键+鼠标右键点击,在此处打开命令行窗口 4.资源管理的地址栏前面加上Cmd路径 管理员运行方式 :系 ...

  5. Docker 环境规划 (Docker安装)

    一.环境规划 支持Java.dotNet.Vue项目构建 二.切换系统镜像源   1.备份      mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.rep ...

  6. CV入坑

    https://www.cnblogs.com/fldev/p/14360149.html

  7. 制作mnist格式数据集

    import os from PIL import Image from array import * from random import shuffle # # 文件组织架构: # ├──trai ...

  8. windows安装WinDump

    1.下载软件,放在C盘: WinDump.exehttps://www.winpcap.org/windump/install/default.htmWinPcap_4_1_3.exe(windows ...

  9. 初学TCP的一些感想

    因为工作原因,想学习一下编程,最近在学习Qt相关的知识,学到了TCP/IP这里,跟着视频做了一个简单的C/S的小例程.例程中没有关于连接状态的判断.经过修改,可是没能达到我要的效果,在百度上进行搜索, ...

  10. [Unity移动端]Mono与IL2Cpp

    参考链接: https://blog.csdn.net/linxinfa/article/details/87358809 https://blog.csdn.net/Aison_/article/d ...