首页 > 编程语言 >刷题笔记——队列(C++)

刷题笔记——队列(C++)

时间:2024-01-12 22:02:14浏览次数:28  
标签:nums 队列 res back C++ int 数组 preSum 刷题

1696. 跳跃游戏 VI - 力扣(LeetCode)

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

一开始你在下标 0 处。每一步,你最多可以往前跳 k 步,但你不能跳出数组的边界。也就是说,你可以从下标 i 跳到 [i + 1, min(n - 1, i + k)] 包含 两个端点的任意位置。

你的目标是到达数组最后一个位置(下标为 n - 1 ),你的 得分 为经过的所有数字之和。

请你返回你能得到的 最大得分 。

刷题笔记——队列(C++)_C++

解题思路

这里使用单调队列,维护队首是最大值,和使用大顶堆原理都是一样的。直接看例子就懂了。

刷题笔记——队列(C++)_学习笔记_02

刷题笔记——队列(C++)_C++_03

刷题笔记——队列(C++)_C++_04

刷题笔记——队列(C++)_数据结构与算法_05

代码实现

class Solution {
public:
    int maxResult(vector<int>& nums, int k) {
        int n = nums.size();
        deque<pair<int,int>> q;
        q.emplace_back(nums[0],0);
        int ans = nums[0];
        for(int i = 1; i < n; i++){
            while(i - q.front().second > k){
                q.pop_front();
            }
            ans = q.front().first + nums[i];
            while(!q.empty() && ans >= q.back().first){
                q.pop_back();
            }
             q.emplace_back(ans,i);
        }
        return ans;
    }
};

918. 环形子数组的最大和 - 力扣(LeetCode)

给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 

环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。

子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], ..., nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。

刷题笔记——队列(C++)_学习笔记_06

解题思路

前缀和+单调队列。这道题和上题很类似,首先将数组延长一倍,转换为在一个长度为2n的数组上,寻找长度不超过n的最大子数组和。而子数组和又转化为了前缀和的问题。需注意出列条件的区别。具体实现见代码。

代码实现

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        int n = nums.size();
        deque<pair<int,int>> q;
        int preSum = nums[0], res = nums[0];
        q.emplace_back(0,preSum);
        for(int i = 1; i < 2*n; i++){
            if(!q.empty() && i - q.front().first > n){
                q.pop_front();
            }
            preSum += nums[i%n];
            res = max(res, preSum-q.front().second);
            while(!q.empty() && q.back().second >= preSum){
                q.pop_back();
            }
            q.emplace_back(i,preSum);
        }
        return res;
    }
};

862. 和至少为 K 的最短子数组 - 力扣(LeetCode)

给你一个整数数组 nums 和一个整数 k ,找出 nums 中和至少为 k 的 最短非空子数组 ,并返回该子数组的长度。如果不存在这样的 子数组 ,返回 -1 。

子数组 是数组中 连续 的一部分。

刷题笔记——队列(C++)_学习笔记_07

解题思路

前缀和+单调队列。同样也是维护双端队列的单调性,在本题中,条件是求最短子数组的长度。那么如何在满足题干条件的前提下缩短子数组长度呢?分两种情况,举例分析:(随便假定的数据,大体是这么理解)

刷题笔记——队列(C++)_数据结构与算法_08

刷题笔记——队列(C++)_C++_09

代码实现

class Solution {
public:
    int shortestSubarray(vector<int>& nums, int k) {
        int n = nums.size();
        int res = INT_MAX;
        vector<long> preSum(n+1);
        for (int i = 1; i <= n; ++i) {
            preSum[i] = preSum[i-1] + nums[i-1];
        }
        deque<int> q;
        q.push_back(0);
        for(int i = 1; i <= n; i++){
            while(!q.empty() && preSum[i] - preSum[q.front()] >= k){
                res = min(res, i - q.front());
                q.pop_front();
            }
            while(!q.empty() && preSum[q.back()] >= preSum[i]){
                q.pop_back();
            }
            q.push_back(i);
        }
        return res == INT_MAX ? -1 : res; 
    }
};

标签:nums,队列,res,back,C++,int,数组,preSum,刷题
From: https://blog.51cto.com/goku0623/9223375

相关文章

  • C/C++程序的内存开辟——《初学C语言第55天》
    //————C/C++程序的内存开辟C++程序内存分配的几个区域://intt=2;//staticintr=1;//voidtest()//{//  statice=1;//  intn=1;//  intarr[10]={1,2,3,4};//  charg[]="helloworld";//  char*p="abcd";//  int*a=(int*)malloc......
  • C++采集亚马逊amazon产品数据教程
    最近亚马逊电商非常火爆,今天我将用C++语言写一个亚马逊商品数据的爬虫程序,只要是用来收集一些产品相关信息。例如产品自身特性以及产品所对应的销量,为了后期布局亚马逊做一些参考,提供数据支持,同时另外我也会用C语言同样写一篇相关的爬虫教程,方便大家借鉴。首先,这是一个非常复杂的项......
  • C++模板例子
    title:"C++模板例子"date:2023-11-02T01:05:25+08:00tags:["C++"]categories:[]draft:false#include<vector>#include<type_traits>usingnamespacestd;classAA{};classBB{};classTest{public:template<cl......
  • C++中 统计程序执行耗时
    C++程序有时需要统计一段代码的执行消耗时间,可以通过类chrono库来进行计算。该库中常常使用两个类来进行计算时间:std::chrono::steady_clock:表示稳定的时钟std::chrono::system_clock:表示当前系统时钟代码如下#include<chrono>usingnamespacestd::chrono;doubleG......
  • 【C++/Qt】QLCDNumber-电子时钟实战
    头文件:#ifndefDIGITALCLOCK_H#defineDIGITALCLOCK_H#include<QLCDNumber>classdigitalClock:publicQLCDNumber{Q_OBJECTpublic:digitalClock(QWidget*parent=0);protected:voidmousePressEvent(QMouseEvent*event);//鼠标点击事件void......
  • 【C/C++】知识点笔记
    1-联合体内嵌结构体初始化赋值union{struct{inti;floatf;char*p;};into;}obj3={1,2.2,"sk",4,9};printf("structinlayunion:%d,%f,%s,%d\n",obj3.i,obj3.f,obj3.p,obj3.o);输出:structin......
  • C++ 拷贝构造函数
    拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:通过使用另一个同类型的对象来初始化新创建的对象。复制对象把它作为参数传递给函数。复制对象,并从函数返回这个对象。如果在类中没有定义拷......
  • agx orin 使用 sdm 刷机后,vscode 使用 C++ 版本的 opencv, 出现红色的波浪线,但是程序
    原因:vscode没有链接好opencv的头文件先找到opencv头文件的位置:sudofind/-iname"opencv"/usr/include/opencv4/usr/include/opencv4/opencv2解决:ctril+sheft+p:打开:c_cpp_properties.json,写入:"includePath":["${workspaceFo......
  • C++设计模式05 —— 装饰模式
    装饰模式过度的使用继承使得派生的子类过多,代码重复度很高,复用性变差。实现加密文件流、加密网络流、加密内存流、缓冲文件流、缓冲网络流、缓冲内存流。如果我们创建一个流基类,然后创建文件流继承流基类,最后创建加密文件流继承文件流、创建缓冲文件流继承文件流。如果这......
  • C++ 类构造函数 & 析构函数
    题目:假定AB为一个类,则执行”ABa(2),b[3],*p[4];“语句时调用该类构造函数的次数为4次。 解析:ABa(2)为调用一次构造函数;ABb[3] 代表b是AB类的对象数组,包含3个对象,因此为调用3次构造函数;AB*p[4]代表p是AB类的对象指针数组,包含4个类对象指针,不调用构造函数。 补......