代码随想录二刷-队列及其应用题目(JS)【重要】

news2024/12/27 12:13:09

239.滑动窗口最大值

题目

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

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

在这里插入图片描述
提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= nums.length

方法

队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。
这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。
1.定义一个从队头到队尾递减的队列
2.输入k个元素,如果不满足递减原则则不加入队列中
3.每移动一个单位,如果滑动窗口移除的元素在队列中,则移除,不在队列中就不管了,然后加入元素看是否满足队列的条件,如果满足,则加入,否则不加入,队头元素即为所求(不弹出)
【有机会做一下单调栈】

代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
    class monoQueue {
        queue;
        constructor() {
            this.queue = [];
        }

        enqueue(val) {
            let back = this.queue[this.queue.length - 1];
            while (this.queue.length && back < val) {
                this.queue.pop();
                // while循环时一定不要忘记更新值
                back = this.queue[this.queue.length - 1]
            }
            this.queue.push(val);
        }

        dequeue(val) {
            // this.front() 是定义数据结构的方法
            // this.queue.pop() 是queue数组本身自带的方法
            if (this.front() == val) {
                this.queue.shift();
            }
        }

        front() {
            return this.queue[0];
        }
    }

    let helpQueue = new monoQueue();
    let resArr = [];
    for (let i = 0;i < k;i++) {
        helpQueue.enqueue(nums[i]);
    }
    resArr.push(helpQueue.front());
    for (let i = k;i < nums.length;i++) {
        helpQueue.enqueue(nums[i]);
        helpQueue.dequeue(nums[i - k]);
        
        resArr.push(helpQueue.front());
    }

    return resArr;
};

347.前k个高频元素

题目

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

  • 输入: nums = [1,1,1,2,2,3], k = 2
  • 输出: [1,2]

示例 2:

  • 输入: nums = [1], k = 1
  • 输出: [1]

提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O ( n log ⁡ n ) O(n \log n) O(nlogn) , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。

方法

思路很简单,大体分为三步

  1. 要统计元素出现频率(Map)
  2. 对频率排序(对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列)
  3. 找出前K个高频元素

优先级队列是一个披着队列外衣的堆,因为优先级队列对外接口只是从对头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列

堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。如果父亲结点大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆

使用大顶堆就要把所有元素都进行排序,那能不能只排序k个元素呢?

所以我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

JS语言中没有堆这种数据结构,我们需要自己定义

排序算法(大顶堆还是小顶堆)

从队尾插入一个元素

删除堆顶元素

在本科时学了很多堆的理论,但之前用Java刷题时并没有涉及,现在给你一个实现那些理论的机会

Java直接给你定义好了

代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
class Heap {
    constructor(compareFn) {
        this.compareFn = compareFn;
        this.queue = [];
    }

    push(val) {
        this.queue.push(val);
        let index = this.queue.length - 1;
        let parent = Math.floor((index - 1) / 2);
        while (parent >= 0 && this.compare(parent,index) > 0) {
            [this.queue[index],this.queue[parent]] = [this.queue[parent],this.queue[index]];

            //更新下标
            index = parent;
            parent = Math.floor((index - 1) / 2);
        }
    }

    pop() {
        const out = this.queue[0];
        this.queue[0] = this.queue.pop();

        // 下沉
        let index = 0;
        let left = 1;

        // 选择左右两个子节点中小的那个(针对小顶堆而言)
        let searchChild = this.compare(left,left + 1) > 0 ? left + 1 : left;

        while (searchChild != undefined && this.compare(index,searchChild) > 0) {
            [this.queue[index],this.queue[searchChild]] = [this.queue[searchChild],this.queue[index]];

            //更新下标
            index = searchChild;
            left = 2 * index + 1;
            searchChild = this.compare(left,left + 1) > 0 ? left + 1 : left;
        }
        return out;
    }

    size() {
        return this.queue.length;
    }

    compare(index1,index2) {
        if (this.queue[index1] == undefined)    return 1;
        if (this.queue[index2] == undefined)    return -1;

        return this.compareFn(this.queue[index1],this.queue[index2]);
    }
}
var topKFrequent = function(nums, k) {
    let heap = new Heap((a,b) => a[1] - b[1]);
    let map = new Map();
    for (let i = 0;i < nums.length;i++) {
        map.set(nums[i],(map.get(nums[i]) || 0) + 1);
    }

    for (const entry of map.entries()) {
        heap.push(entry);

        if (heap.size() > k) {
            heap.pop();
        }
    }
    let resArr = [];
    for (let i = k - 1;i >= 0;i--) {
        resArr[i] = heap.pop()[0];
    }
    return resArr;
}; 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/442852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Thinkpad-t470电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件型号驱动情况 主板Thinkpad-t470 处理器Intel Core i7-6600U 2.6GHz / 3.4Ghz Turbo已驱动 内存16GB DDR4 2666Mhz (SK Hynix)已驱动 硬盘Intel SSD Pro 7600P 51…

与Linux的文件权限有关的知识

在Linux系统中&#xff0c;每个文件都有一个所有者和一个用户组。此外&#xff0c;系统还定义了一个“其他人”分类。 文件的所有者通常是创建该文件的用户&#xff0c;而用户组则是在创建该文件时指定的。如果没有指定&#xff0c;则默认为创建用户的主用户组。用户组可以在文…

核心业务1:账户绑定业务

核心业务1:账户绑定业务 1.业务流程图 2.账户绑定数据库设计 3.账户绑定业务流程 4.代码逻辑 5.代码逻辑细节 核心业务1:账户绑定业务 1.业务流程图 ①用户绑定数据到商户平台(已

C++map/set与unordered系列的区别

文章目录 map/set与unordered系列的区别map/set与unordered系列的性能对比测试总结 map/set与unordered系列的区别 1: map/set遍历时是有序的,unordered_map/unordered_set遍历时是无序的. 以set和unordered_set容器为例: 2: map/set是双向迭代器,底层数据结构为红黑树,unor…

重磅 | Shifu物联网开发框架成为CNCF认证项目

近日&#xff0c;边无际Shifu项目被收录进CNCF云原生全景图&#xff0c;成为了云原生计算基金会认证的项目之一。此次收录证明了Shifu具备了符合CNCF标准的技术能力和良好的社区发展&#xff0c;展现了Shifu在云原生计算领域的实力和可信度&#xff0c;巩固了Shifu在云原生领域…

J2EE,Java EE,Jakarta EE 命名之间的恩恩怨怨

介绍 简单来说&#xff0c;上面所有的名字指的都是一个东西 Java Platform, Enterprise Edition 上面的几个名词都是下面的内容的简写&#xff1a; J2EE(Java 2 Platform, Enterprise Edition)Java EE (Java Platform, Enterprise Edition)Jakarta EE(Jakarta Enterprise Edi…

learn_C_deep_1 (C程序补充知识、变量的声明和定义、声明和定义的区别)

目录 C程序补充知识 变量的声明和定义 1.什么是变量&#xff1f; 2.变量的本质是什么&#xff1f; - 所有的变量都要在内存的某个位置开辟空间 3.变量的定义和声明形式、初始化和赋值的区别 4.为什么要定义变量 声明和定义的区别 C程序补充知识 先让我们来看一段C语言…

史上最严宝宝口粮新国标出台,DHA和维生素D可能无需额外补充了

自2023年2月22日起&#xff0c;我国婴幼儿配方食品&#xff08;以下简称配方奶&#xff09;新国标开始实施。这意味着2023年2月22日以后在中国上架销售的配方奶必须符合新国标&#xff0c;重新取得国家市场监督管理总局食品评审中心&#xff08;CFE-SAMR&#xff09;的注册。这…

【单片机】基于Arduino cli和VS Code配置开发环境,彻底抛弃Arduino IDE

文章目录 0 前言1 VS Code的优势和Arduino IDE的劣势2 前期准备3 Arduino cli3.1 Arduino cli是什么3.2 下载与安装3.3 基本使用3.4 开发环境配置 4 VS Code配置5 参考链接 0 前言 之前有在电脑上基于VS Code配置Arduino环境&#xff0c;大致方法就是在安装Arduino IDE的前提下…

SCT2650STER,可以实现低成本升降压

市面上主流的中高压升降压拓扑方案有四开关管升降压控制芯片、SEPIC/反激控制芯片等。实际上四开关管升降压芯片成本很高&#xff0c;而SEPIC/反激控制芯片设计复杂。 如果仅需要升降压功能&#xff0c;功率较小&#xff0c;不需要隔离时&#xff0c;本篇解决方案将以SCT2650为…

真题详解(地址索引)-软件设计(五十一)

真题详解&#xff08;单元测试&#xff09;-软件设计&#xff08;五十)https://blog.csdn.net/ke1ying/article/details/130189173?spm1001.2014.3001.5501 指令寻址方式 有四种&#xff0c;直接寻址&#xff0c;寄存器寻址&#xff0c;隐含寻址&#xff0c;立即寻址。 按寻…

基于高斯两步移动搜寻法(2SFCA)的城市绿地可达性分析

【2SFCA的基本思路,可以略过】 对每个供给点j,搜索所有在j搜寻半径(d0)范围内的需求点(k),计算供需比Rj;对每个需求点i,搜索所有在i搜寻半径(d0)范围内的供给点(j),将所有的供需比Rj加总得到i点的可达性Ai。 【数据】 成都市城区绿地数据、各街道小区数据、路网…

基于Rush.js的Monorepo实战

基于Rush.js的Monorepo入门实战 概述 Monorepo是一种软件开发模式&#xff0c;它将多个项目或组件存储在同一个代码库中&#xff0c;而不是将它们分散到多个库中。这样做可以方便跨项目的代码重用、版本控制、依赖管理等&#xff0c;被广泛应用于大型软件公司的开发流程中。 …

动力节点Vue3笔记——Vue程序初体验

目录 一、Vue程序初体验 1.1 下载并安装vue.js 1.2 第一个Vue程序 1.3 Vue的data配置项 1.4 Vue的template配置项 一、Vue程序初体验 可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的&#xff0c;对我们编写Vue程序起不到太大的作用&#xff0c;…

C语言从入门到精通第4天(1~3天的扩展)

1~3天的扩展 拓展数据类型sizeof关键字整型数据的打印格式字符类型的输出格式ASCII码表转义字符进制 拓展数据类型 在开发过程中我们需要处理各种类型的数据&#xff0c;C语言处理基本类型还有其他的类型&#xff1a; sizeof关键字 C语言中可以通过sizeof关键字获取某个数据…

Java源码(三)SpringBoot Web容器应用上下文

思维导图 本文主要分析ServletWebServerApplicationContext源码 SpringBoot Web容器应用上下文&#xff08;这是个人的翻译, 如有不足之处还望指出, 大佬勿喷!!!&#xff09; 1.自我思考及复盘 备注&#xff1a; 自我思考及复盘是为了养成带着问题阅读源码及阅读完源码后总结…

echarts 雷达图

Echarts 常用各类图表模板配置 注意&#xff1a; 这里主要就是基于各类图表&#xff0c;更多的使用 Echarts 的各类配置项&#xff1b; 以下代码都可以复制到 Echarts 官网&#xff0c;直接预览&#xff1b; 图标模板目录 Echarts 常用各类图表模板配置一、雷达图二、环形图三…

27 个Python数据科学库实战案例 (附代码)

为了大家能够对人工智能常用的 Python 库有一个初步的了解&#xff0c;以选择能够满足自己需求的库进行学习&#xff0c;对目前较为常见的人工智能库进行简要全面的介绍。 1、Numpy NumPy(Numerical Python)是 Python的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算…

US News退榜风波后,发布最新美国最佳法学院和医学院排名

从2022年11月开始&#xff0c;美国权威排名机构US News不断陷入风波。耶鲁大学法学院率先宣布退出US News法学院排名&#xff0c;先是法学院&#xff0c;后是医学院&#xff0c;包括哈佛大学大学、斯坦福大学、哥伦比亚大学和加州大学伯克利分校等名校也纷纷宣布退出。 这些老…

【C语言】const关键字的作用

文章目录 一. const修饰变量二. const修饰指针三. const修饰函数参数 一. const修饰变量 被 const 修饰的变量具有常属性&#xff0c;这里的常属性指的是变量的值不能被修改 int main() {// const可以写在类型之前&#xff0c;也可以写在类型之后int const a 10;a 20;// er…