【单调队列】LeetCode1425:带限制的子序列和

作者推荐

map|动态规划|单调栈|LeetCode975:奇偶跳

涉及知识点

单调队列

题目

给你一个整数数组 nums 和一个整数 k ,请你返回 非空 子序列元素和的最大值,子序列需要满足:子序列中每两个 相邻 的整数 nums[i] 和 nums[j] ,它们在原数组中的下标 i 和 j 满足 i < j 且 j - i <= k 。
数组的子序列定义为:将数组中的若干个数字删除(可以删除 0 个数字),剩下的数字按照原本的顺序排布。
示例 1:
输入:nums = [10,2,-10,5,20], k = 2
输出:37
解释:子序列为 [10, 2, 5, 20] 。
示例 2:
输入:nums = [-1,-2,-3], k = 1
输出:-1
解释:子序列必须是非空的,所以我们选择最大的数字。
示例 3:
输入:nums = [10,-2,-10,-5,20], k = 2
输出:23
解释:子序列为 [10, -2, -5, 20] 。
参数范围
1 <= k <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4

单调队列

时间复杂度😮(n)
由于是非空子序列,所以一定有结尾。枚举子序列的结尾,对于每个下标i,有以下两种情况:

方式一只有一个元素nums[i]的子系列
方式一以nums[j]结尾的子序列,再加上nums[i]

如果存在以nums[j]结尾的子序列,且其和为正则选择方法二,如果有多个j,取和最大的。

单调队列

vRet[i]是以nums[i]结尾的最大子系列和。
queIndex记录了[0,i) 淘汰以下两类下标:
一,下标小于i-k,从队尾淘汰。
二,j1<j2,且vRet[j1]<=vRet[j2]。淘汰j1。j1能被i选择,则j2也能被选择。而vRet[i2]较大,所以淘汰j1不会影响结果。

代码

核心代码

class Solution {
public:int constrainedSubsetSum(vector<int>& nums, int k) {m_c = nums.size();vector<int> vRet(m_c);std::deque<int> queIndex;for (int i = 0; i < m_c; i++){if (queIndex.size() && (queIndex.front() < i - k)){queIndex.pop_front();}const int pre = (queIndex.size() ? vRet[queIndex.front()] : 0);vRet[i] = max(0, pre) + nums[i];while (queIndex.size() && (vRet[queIndex.back()] <= vRet[i])){queIndex.pop_back();}queIndex.emplace_back(i);}return *std::max_element(vRet.begin(), vRet.end());}int m_c;
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{vector<int> nums;int k;{Solution sln;nums = { 10,2,-10,5,20 },k=2;auto res = sln.constrainedSubsetSum(nums,k);Assert(37, res);}{Solution sln;nums = { -1,-2,-3 }, k =1;auto res = sln.constrainedSubsetSum(nums, k);Assert(-1, res);}{Solution sln;nums = { 10,-2,-10,-5,20 }, k = 2;auto res = sln.constrainedSubsetSum(nums, k);Assert(23, res);}//CConsole::Out(res);
}

2023年2月版

 class Solution {public:int constrainedSubsetSum(vector<int>& nums, int k) {m_c = nums.size();vector<int> indexs, maxs;int iHasDo = 0;for (int i = 0; i < nums.size(); i++ ){const auto& num = nums[i];while ((indexs.size() > iHasDo) && (i - indexs[iHasDo] > k)){iHasDo++;}int iValue = ( maxs.size() ==  iHasDo) ? 0 : maxs[iHasDo];iValue = max(iValue, 0) + num;while ((maxs.size() > iHasDo) && (iValue >= maxs.back())){maxs.pop_back();indexs.pop_back();}indexs.push_back(i);maxs.push_back(iValue);}return *std::max_element(maxs.begin(), maxs.end());}int m_c;};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法C++ 实现。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解Vue3中的基础路由和动态路由

本文主要介绍Vue3中的基础路由和动态路由。 目录 一、基础路由二、动态路由 Vue3中的路由使用的是Vue Router库&#xff0c;它是一个官方提供的用于实现应用程序导航的工具。Vue Router在Vue.js的核心库上提供了路由的功能&#xff0c;使得我们可以在单页应用中实现页面的切换、…

Linux使用circos

1.在conda中安装bioconda conda install -c bioconda circos -y # 测试是否所有的module都安装好了 circos -module # 所有都显示OK则成功 ok 0.39 Font::TTF::Font ok 2.68 GD ok 0.2 GD::Polyline ... .... 2.检查模块是否齐全 circos -module 3.下…

记一次若依ruoyi-ui(Vue2) 关闭tab页并打开新页面

网上教程很多&#xff0c;但是都是给前端代码段&#xff0c;都不知道怎么使用&#xff08;本人菜鸟一个&#xff09;&#xff0c;今天记一次完整的&#xff1a; 在你需要关闭的tab页面&#xff0c;加入以下代码&#xff1a; handleCommit()是我需要关闭页面的方法&#xff0c…

DDD领域驱动设计系列-原理篇-战术设计

概述 上篇战略设计产出了领域及问题域领域模型&#xff1b;详见&#xff1a;DDD领域驱动设计系列-原理篇-战略设计-CSDN博客 战术设计篇聚焦如何落地&#xff0c;包含实际解决方案模型落地&#xff0c;架构分层&#xff08;Clean&#xff0c;CQRS&#xff09;&#xff0c;Rep…

MacOS+Homebrew+iTerm2+oh my zsh+powerlevel10k美化教程

MacOS终端 你是否已厌倦了MacOS终端的大黑屏&#xff1f; 你是否对这种美观的终端抱有兴趣&#xff1f; 那么&#xff0c;接下来我将会教你用最简单的方式来搭建一套自己的终端。 Homebrew的安装 官网地址&#xff1a;Homebrew — The Missing Package Manager for macOS (o…

为什么要使用vite

vue ——&#xff09;webpack 全部读取完毕才显示&#xff1a; vite:只读取修改的部分&#xff0c;速度比较快

3.java——继承及拓展(保姆级别教程,万字解析,匠心制作)

三.继承——节省了共有属性和方法的代码&#xff1a;语法 class Student extends Person 1.继承基础 1.继承首先是面向对象中非常强的一种机制&#xff0c;他首先可以复用代码&#xff08;name ,age&#xff09;&#xff0c;让我们的获得了Person全部功能和属性&#xff0c;只…

分而治之:Fork/Join框架(构造一个1到200 000求和的任务)

Fork一词的原始含义是吃饭用的叉子&#xff0c;也有分叉的意思。在linux平台中&#xff0c; 方法fork用来创建子进程。使得系统进程可以多一个执行分组。 而join方法这里表示等待&#xff0c;也就是使用fork方法后系统多了一个执行分支(线程) 所以需要等待这个执行分支执行完毕…

实习课知识整理3:首页商品列表的展示

对于一个购物商城的项目&#xff0c;主体还得是商品&#xff0c;这篇博客主要介绍如何将数据库中的信息渲染到页面上&#xff0c;这边后端是SpringBoot,前端是html配合thymeleaf模板 1. 编写查询数据库的方法 在这边我在页面上需要两部分的信息&#xff0c;一个是所有的商品&am…

vue前端上传图片到阿里云OSS,超详细上传图片与视频教程

vue前端直传图片与视频到阿里云OSS 1. 简介与日常使用2. 为什么要这么干&#xff1f;是因为我司后端不行吗&#xff1f;&#xff1f;&#xff1f;&#xff08;确实&#xff01;&#xff09;3. vue前端直传的操作4. 如何上传到阿里OSS指定文件夹呢? 1. 简介与日常使用 阿里云…

html5实现最智能大气的公司年会抽奖(源码)

文章目录 1.设计来源1.1 主界面1.3 数据配置1.4 抽奖效果1.5 中奖效果 2.效果和源码配置2.1 动态效果2.2 员工信息配置2.3 奖品信息配置2.4 抽奖音效配置2.5 源代码2.6 项目结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/…

Python字符串处理全攻略(三):常用内置方法轻松掌握

目录 引言Python字符串常用内置方法str.index()功能介绍语法注意事项总结 str.startswith()功能介绍语法示例注意事项 str.expandtabs()功能介绍语法示例注意事项总结 str.splitlines()功能介绍语法示例注意事项总结 str.swapcase()功能介绍语法示例注意事项 结束语 引言 欢迎…