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. 怎样修改linux内核

    1.先查看linux内核 uname -a 2.打开内核配置文件 sudo vi /etc/default/grub 3.跟新grub文件 sudo update-grub 4.最后重启电脑 sudo ...

  2. 冲刺总结-day7

    完成任务:前端设计 设计系统前端,利用html和css对登录页面和进入系统操作界面进行界面化设计,使系统看起来美观.简洁. 一.设计思路 利用HTML对整个网页页面进行布局和设计内容,使用CSS对每一 ...

  3. 华为服务器修改ibmc账号密码、配置raid5、安装系统

    修改ibmc账号密码 转载自:https://www.cnblogs.com/mtactor/p/2288V5.html  昵称: mtactor 方法一:采用网线直连管理口 1.使用网线直接连接服务 ...

  4. SqlServer 不能收缩 ID 为 %s 的数据库中 ID 为 %s 的文件,因为它正由其他进程收缩或为空。

    SQLServer数据库通常都不建议进行SHRINKFILE操作,因为SHRINKFILE不当会造成一定的性能问题. 但是当进行了某些操作(例如某个超大的日志类型表转成分区表切换了数据文件),数据库某 ...

  5. nodejs res常用的返回方式

    常用的返回方式有四种 res.json([status|body], [body])  以json的形式返回数据res.render(view [, locals] [, callback])  返回 ...

  6. HBase架构、模型、特点

    如需大数据开发整套视频(hadoop\hive\hbase\flume\sqoop\kafka\zookeeper\presto\spark):请联系QQ:1974983704 1.HBase概述 H ...

  7. centos安装k8s注意点

    安装方法,参考 https://blog.csdn.net/frankgy01/article/details/127936367 https://www.cnblogs.com/yangzp/p/1 ...

  8. pragma pack(字节对齐用法)---C语言

    #pragma pack(4) typedef struct { char buf[3]; word a; }kk; #pragma pack() 对齐的原则是min(sizeof(word ),4) ...

  9. Python笔记--练习题(都来瞧一瞧,看一看嘞)

    利用Python对文件进行操作 重新写入的文件如下图所示: 统计学生成绩文件的最高分最低分和平均分 Python如何统计英文文章出现最多的单词 Python统计目录下的文件大小 Python按照文件后 ...

  10. Android笔记--案例:登录界面以及登录逻辑

    登录界面的实现 就是说,界面的绘制,并没有什么难度,只要控制好空间的分配就可以了 登录的逻辑实现 获取验证码.忘记密码的界面跳转.登录的实现: 确认文本框的输入内容是否符合题意: