【代码随想录】算法训练营 第十三天 第五章 栈与队列 Part 3

news2024/11/17 23:40:55

239. 滑动窗口最大值

题目

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

返回 滑动窗口中的最大值 

思路

一开始我是直接暴力两层循环的,但是Time Limit了,所以只好乖乖看随想录了。

随想录的方法很妙,是自己定义一个单调队列,这个队列是基于deque的,deque是一种底层容器,是queue的基础。

这个单调队列的作用是,固定长度,每次从队尾添加元素,如果这个元素是第一个,那就直接加进去,如果不是的话,就要考虑队尾元素和它的大小关系了,因为我们想要得到的是一个从队尾到队头单调递增的队列,所以如果队尾元素小于新加的元素的话,就得把队尾pop掉;

单调队列的另一个重要操作是将元素出队,也就是从队头出队,为什么要出队呢,因为我们的这个单调队列是一个在题目所给的数组上滑动的窗口,每次新加入一个元素就得把尾巴那里的元素pop掉,但是在队列里面,只能把队头元素pop掉,这时候只要判断出队的元素和队头元素相不相等了,如果相等就直接pop掉,不相等就不pop,因为在之前添加元素的时候,这个元素就已经被pop了;

最后就是实现返回单调队列最大值作为答案之一了,这个操作很简单,直接返回队头元素就好,因为队列从尾到头单调递增。

现在唯一需要的工具已经定义好了,接下来就正式解题,首先就是定义一个单调队列,先往这个队列里加k个元素,之后再来一个for循环,这个循环从下标为k的元素开始,每次先pop掉当前元素的前面第k个元素,再新加进来一个下标为i的元素,然后往答案容器里push_back一下队列的队头元素即可。

代码

class Solution {
private:
    class MyQueue {
    public:
        deque<int> que;
        // 每次要pop元素时都要看看要弹出的是不是队头元素,是的话就弹出
        // 还要判断这时候队列是否为空
        void pop(int value) {
            if (!que.empty() && value == que.front()) {
                que.pop_front();
            }
        }
        // 如果push的数值大于尾端的数值,那就将尾端数值弹出,直到push的数值小于等于尾端数值为止
        // 这样就可以保持队列里的数值是从尾到头单调递增的了
        void push(int value) {
            while (!que.empty() && value > que.back()) {
                que.pop_back();
            }
            que.push_back(value);
        }
        // 查询队列里的最大值,直接返回队头元素即可,因为队列是从尾到头递增的
        int front() {
            return que.front();
        }
    };
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MyQueue que;
        vector<int> result;
        for (int i = 0; i < k; i++) {
            que.push(nums[i]);
        }
        result.push_back(que.front());
        for (int i = k; i < nums.size(); i++) {
            que.pop(nums[i - k]);
            que.push(nums[i]);
            result.push_back(que.front());
        }
        return result;
    }
};

347. 前 K 个高频元素

题目

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

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

示例 2:

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

思路

这道题很容易可以想要用map来统计每个数字出现的次数,但是还要对次数进行排序,相当于是按value值来排序,这就不好做了,所以这里也定义了一个之前闻所未闻的小顶堆。

堆其实就是完全二叉树,大顶堆从上到下从左到右递增,而小顶堆则是从上到下从左到右递减,所以大顶堆里顶最大,小顶堆里顶最小,我们把map中的键值对放入小顶堆中,小顶堆就会按照value值自动排序,把最小的放在上面,这样只需要留下k个value最大的键值对就好了。

代码

class Solution {
public:
    // 小顶堆
    class mycomparison {
    public:
        bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
            return lhs.second > rhs.second;
        }
    };
    vector<int> topKFrequent(vector<int>& nums, int k) {
        // 要统计元素出现频率
        unordered_map<int, int> map; // map<nums[i],对应出现的次数>
        for (int i = 0; i < nums.size(); i++) {
            map[nums[i]]++;
        }

        // 对频率排序
        // 定义一个小顶堆,大小为k
        priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison> pri_que;

        // 用固定大小为k的小顶堆,扫面所有频率的数值
        for (unordered_map<int, int>::iterator it = map.begin(); it != map.end(); it++) {
            pri_que.push(*it);
            if (pri_que.size() > k) { // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                pri_que.pop();
            }
        }

        // 找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒序来输出到数组
        vector<int> result(k);
        for (int i = k - 1; i >= 0; i--) {
            result[i] = pri_que.top().first;
            pri_que.pop();
        }
        return result;

    }
};

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

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

相关文章

Python学习笔记——MYSQL,SQL核心

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; SQL语言分类 SQL注释 库管理 表管理 数据操作 分组聚合 分页限制 需要注意的是关键字的顺序不可以错乱&#xff0c;否则会报错其中LIMIT关键字的n是指从第n个开始&#xff0c;m是指查…

http post协议实现简单的rpc协议,WireShark抓包分析

文章目录 1.http 客户端-RPC客户端1.http 服务端-RPC服务端3.WireShark抓包分析3.1客户端到服务端的HTTP/JSON报文3.2服务端到客户端的HTTP/JSON报文 1.http 客户端-RPC客户端 import json import requests# 定义 RPC 客户端类 class RPCClient:def __init__(self, server_url…

【蓝桥杯选拔赛真题43】python二进制位数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python二进制位数 一、题目要求 1、编程实现 2、输入输出 二、算法分析

深入浅出Apache SeaTunnel SQL Server Sink Connector

在大数据时代&#xff0c;数据的迁移和流动已经变得日益重要。为了使数据能够更加高效地从一个源流向另一个目标&#xff0c;我们需要可靠、高效和易于配置的工具。今天&#xff0c;我们将介绍 JDBC SQL Server Sink Connector&#xff0c;这是一个专为 SQL Server 设计的连接器…

嵌入式linux总线设备驱动模型分析

嵌入式linux系统按照&#xff0c;分层&#xff0c;抽象的思想&#xff0c;按照这样的思想来设计我们的程序可以更容易写出耦合性低、独立性强、可重用性强的代码。 Linux内核中更是存在着更多的分离、分层思想的代码&#xff0c;platform平台设备驱动就是用了这样的思想。本篇…

机器学习(新手入门)-线性回归 #房价预测

题目&#xff1a;给定数据集dataSet&#xff0c;每一行代表一组数据记录,每组数据记录中&#xff0c;第一个值为房屋面积&#xff08;单位&#xff1a;平方英尺&#xff09;&#xff0c;第二个值为房屋中的房间数&#xff0c;第三个值为房价&#xff08;单位&#xff1a;千美元…

pv操作题目笔记

对于 pv 操作分以下几步走 什么是pv操作 PV操作在进程同步中通常指的是信号量&#xff08;Semaphore&#xff09;操作。信号量是一种用于控制多个并发进程或线程之间的同步和互斥访问的同步工具。PV操作通常涉及两个基本操作&#xff1a;P操作&#xff08;wait操作&#xff0…

算法通关村第十一关青铜挑战——移位运算详解

大家好&#xff0c;我是怒码少年小码。 计算机到底是怎么处理数字的&#xff1f; 数字在计算机中的表示 机器数 一个数在计算机中的二进制表示形式&#xff0c;叫做这个数的机器数。 机器数是带符号的&#xff0c;在计算机用一个数的最高位存放符号&#xff0c;正数为0&am…

【剑指Offer】:删除链表中的倒数第N个节点(此题是LeetCode上面的)剑指Offer上面是链表中的倒数第K个节点

给定一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&#xff1a;…

计算机网路第3章-运输层

概述和运输层服务 运输层协议为运行在不同主机上的应用进程提供了逻辑通信&#xff0c;从应用程序角度看&#xff0c;通过使用逻辑通信&#xff0c;就好像运行在不同主机上的进程直接相连在一起一样。 运输层和网络层的关系 网络层提供主机之间的通信&#xff0c;而运输层提…

面试官的一句话,让五年功能测试老手彻夜难眠!

小王是一名软件测试工程师&#xff0c;已经在目前的公司做了四五年的功能测试。虽然一直表现得非常努力&#xff0c;但他还是没能躲过裁员。只能被动跳槽&#xff0c;寻找更好的职业机会。 然而事情并没有像他想象中那样顺利。在多次面试中小王屡屡碰壁&#xff0c;被面试官吐槽…

leetcode:面试题 17.04. 消失的数字(找单身狗/排序/公式)

一、题目&#xff1a; 函数原型&#xff1a;int missingNumber(int* nums, int numsSize) 二、思路&#xff1a; 思路1 利用“找单身狗”的思路&#xff08;n^n0&#xff1b;0^nn&#xff09;&#xff0c;数组中有0-n的数字&#xff0c;但缺失了一个数字x。将这些数字按位异或0…

Antv G6入门之旅--combo图

目录 什么是AntV G6 G6 的特性 G6 文档 安装 1 在项目中使用 NPM 包引入 2 在 HTML 中使用 CDN 引入 使用 Step 1 创建容器 Step 2 数据准备 Step 3 创建关系图 Step 4 配置数据源&#xff0c;渲染 React 中使用 G6 Combo图 什么是AntV G6 G6 是一个图可视化引擎…

深度学习模型不确定性方法对比

©PaperWeekly 原创 作者&#xff5c;崔克楠 学校&#xff5c;上海交通大学博士生 研究方向&#xff5c;异构信息网络、推荐系统 本文以 NeurIPS 2019 的 Can You Trust Your Model’s Uncertainty? Evaluating Predictive Uncertainty Under Dataset Shift 论文为主线…

机器学习笔记 - 特斯拉的占用网络简述

一、简述 ​ 2022 年,特斯拉宣布即将在其车辆中发布全新算法。该算法被称为occupancy networks,它应该是对Tesla 的HydraNet 的改进。 自动驾驶汽车行业在技术上分为两类:基于视觉的系统和基于激光雷达的系统。后者使用激光传感器来确定物体的存在和距离,而视觉系统…

acwing第 126 场周赛 (扩展字符串)

5281. 扩展字符串 一、题目要求 某字符串序列 s0,s1,s2,… 的生成规律如下&#xff1a; s0 DKER EPH VOS GOLNJ ER RKH HNG OI RKH UOPMGB CPH VOS FSQVB DLMM VOS QETH SQBsnDKER EPH VOS GOLNJ UKLMH QHNGLNJ Asn−1AB CPH VOS FSQVB DLMM VOS QHNG Asn−1AB&#xff0c;其…

day10_面向对象_抽象_接口

今日内容 1.作业 2.final 3.抽象 4.接口 零、复习 按从大到小的顺序写出访问修饰符 public > protected > package (default)> private static修饰属性和方法的特点在内存的特点: 在方法区(不是在堆,也不是在栈)初始化的特点: 随类(字节码文件)加载到内存已经初始化使…

基于大数据的时间序列股价预测分析与可视化 - lstm 计算机竞赛

文章目录 1 前言2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &…

Redis不止能存储字符串,还有List、Set、Hash、Zset,用对了能给你带来哪些优势?

文章目录 &#x1f31f; Redis五大数据类型的应用场景&#x1f34a; 一、String&#x1f34a; 二、Hash&#x1f34a; 三、List&#x1f34a; 四、Set&#x1f34a; 五、Zset &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO…

1300*B. Road Construction(构造菊花图)

Problem - 330B - Codeforces 解析&#xff1a; 1到任一点距离不超过二&#xff0c;并且有部分点不可以连边&#xff0c;直接统计所有不能连边的点&#xff0c;从之外的点中选一个点当作中心&#xff0c;构造菊花图即可。 #include<bits/stdc.h> using namespace std; i…