news 2026/5/1 5:42:35

LeetCode 3013.将数组分成最小总代价的子数组 II:两个堆维护k-1小 + 滑动窗口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 3013.将数组分成最小总代价的子数组 II:两个堆维护k-1小 + 滑动窗口

【LetMeFly】3013.将数组分成最小总代价的子数组 II:两个堆维护k-1小 + 滑动窗口

力扣题目链接:https://leetcode.cn/problems/divide-an-array-into-subarrays-with-minimum-cost-ii/

给你一个下标从0开始长度为n的整数数组nums和两个整数kdist

一个数组的代价是数组中的第一个元素。比方说,[1,2,3]的代价为1[3,4,1]的代价为3

你需要将nums分割成k连续且互不相交的子数组,满足第二个子数组与第k个子数组中第一个元素的下标距离不超过dist。换句话说,如果你将nums分割成子数组nums[0..(i1- 1)], nums[i1..(i2- 1)], ..., nums[ik-1..(n - 1)],那么它需要满足ik-1- i1<= dist

请你返回这些子数组的最小总代价。

示例 1:

输入:nums = [1,3,2,6,4,2], k = 3, dist = 3输出:5解释:将数组分割成 3 个子数组的最优方案是:[1,3] ,[2,6,4] 和 [2] 。这是一个合法分割,因为 ik-1- i1等于 5 - 2 = 3 ,等于 dist 。总代价为 nums[0] + nums[2] + nums[5] ,也就是 1 + 2 + 2 = 5 。 5 是分割成 3 个子数组的最小总代价。

示例 2:

输入:nums = [10,1,2,2,2,1], k = 4, dist = 3输出:15解释:将数组分割成 4 个子数组的最优方案是:[10] ,[1] ,[2] 和 [2,2,1] 。这是一个合法分割,因为 ik-1- i1等于 3 - 1 = 2 ,小于 dist 。总代价为 nums[0] + nums[1] + nums[2] + nums[3] ,也就是 10 + 1 + 2 + 2 = 15 。 分割 [10] ,[1] ,[2,2,2] 和 [1] 不是一个合法分割,因为 ik-1和 i1的差为 5 - 1 = 4 ,大于 dist 。 15 是分割成 4 个子数组的最小总代价。

示例 3:

输入:nums = [10,8,18,9], k = 3, dist = 1输出:36解释:将数组分割成 4 个子数组的最优方案是:[10] ,[8] 和 [18,9] 。这是一个合法分割,因为 ik-1- i1等于 2 - 1 = 1 ,等于 dist 。总代价为 nums[0] + nums[1] + nums[2] ,也就是 10 + 8 + 18 = 36 。 分割 [10] ,[8,18] 和 [9] 不是一个合法分割,因为 ik-1和 i1的差为 3 - 1 = 2 ,大于 dist 。 36 是分割成 3 个子数组的最小总代价。

提示:

  • 3 <= n <= 105
  • 1 <= nums[i] <= 109
  • 3 <= k <= n
  • k - 2 <= dist <= n - 2

解题方法:有序集合 + 滑动窗口

n u m s numsnums第一个元素必选,剩下k − 1 k-1k1个元素的起始位置间隔必须≤ d i s t \leq distdist。使用一个大小为d i s t + 1 dist+1dist+1的滑动窗口,每次求这个窗口中k − 1 k-1k1小元素的和。

问题变成了滑动窗口向右滑动过程中,窗口中不断新增一个元素、移除一个元素的状态下如何保持计算k − 1 k-1k1小的元素有哪些:

我们可以使用两个有序集合,一个叫s t a g e stagestage代表(正在舞台上的)k − 1 k-1k1小元素,一个叫c a n d i d a t e candidatecandidate代表在窗口中但(暂)未被选中的元素。

窗口右移过程中,假设要新加入窗口的元素是i n inin,移除窗口的元素是o u t outout

对于o u t outout有:

  • 如果o u t outoutc a n d i d a t e candidatecandidate候选集合中,那么o u t outout永无上台之日,直接移出候选
  • 如果o u t outouts t a g e stagestage选中集合中,那么o u t outout是时候退役了,移出s t a g e stagestage集合,并更新集合中元素之和

对于i n inin有:

  • 如果i n inins t a g e stagestage中最大元素小,说明更优秀的人来了,移出s t a g e stagestage集合中最大的那个,将i n inin加入s t a g e stagestage集合,并更新s t a g e stagestage集合中元素之和
  • 否则,将i n inin加入候选

之后进行s t a g e stagestage集合大小的调整:

  • 如果s t a g e stagestage集合小于k − 1 k-1k1,说明有人退役暂无人顶上,从c a n d i d a t e candidatecandidate中选最小的那个顶上(移出c a n d i d a t e candidatecandidate并加入s t a g e stagestage),并更新s t a g e stagestage集合中元素之和
  • 如果s t a g e stagestage集合大于k + 1 k+1k+1,说明有更优秀的人来了,要把s t a g e stagestage中最大的那个移出并加入到c a n d i d a t e candidatecandidate,并更新s t a g e stagestage集合中元素之和

整个滑动窗口移动的过程中,所有s t a g e stagestage元素和中最小的那个即为答案。

为了方便计算,我们开局直接把k kk减一。

  • 时间复杂度O ( n log ⁡ d i s t ) O(n\log dist)O(nlogdist)
  • 空间复杂度O ( d i s t ) O(dist)O(dist)

AC代码

C++
/* * @LastEditTime: 2026-02-03 22:11:11 */typedeflonglongll;classSolution{public:llminimumCost(vector<int>&nums,intk,intdist){k--;multiset<ll>stage(nums.begin()+1,nums.begin()+dist+2),candidate;ll ans=accumulate(nums.begin(),nums.begin()+dist+2,0ll);while(stage.size()>k){intretiree=*stage.rbegin();stage.erase(prev(stage.end()));ans-=retiree;candidate.insert(retiree);}ll nowAns=ans;for(intend=dist+2;end<nums.size();end++){intin=nums[end],out=nums[end-dist-1];// outmultiset<ll>::iterator it=candidate.find(out);if(it!=candidate.end()){candidate.erase(it);}else{stage.erase(stage.find(out));nowAns-=out;}// inif(in<*stage.rbegin()){stage.insert(in);nowAns+=in;}else{candidate.insert(in);}// resizeif(stage.size()==k-1){intnewActor=*candidate.begin();candidate.erase(candidate.begin());stage.insert(newActor);nowAns+=newActor;}elseif(stage.size()==k+1){intretiree=*stage.rbegin();stage.erase(prev(stage.end()));nowAns-=retiree;candidate.insert(retiree);}ans=min(ans,nowAns);}returnans;}};#ifdefined(_WIN32)||defined(__APPLE__)/* [1,3,2,6,4,2] 3 3 5 */intmain(){string s;inta,b;while(cin>>s>>a>>b){Solution sol;vector<int>v=stringToVector(s);cout<<sol.minimumCost(v,a,b)<<endl;}return0;}#endif

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 14:36:00

BEAR基准深度解析:多模态大语言模型的体现能力评估与提升指南

BEAR基准是首个全面评估多模态大语言模型(MLLM)体现能力的综合测试&#xff0c;包含4469个多模态样本。研究发现当前MLLM表现普遍不佳(20%-40%)&#xff0c;最佳模型GPT-5仅达52%&#xff0c;远低于人类84%基准。研究团队提出BEAR-Agent多模态代理&#xff0c;成功将GPT-5性能提…

作者头像 李华
网站建设 2026/4/28 23:01:45

NFL新一代数据分析系统十年创新历程

每次NFL比赛的每一次对抗都会产生大量的物理数据。22名球员在几分之一秒内加速、碰撞并改变方向&#xff0c;而橄榄球则在有序的混乱中划出一道轨迹。然而在这项运动的大部分历史中&#xff0c;许多复杂性都未被测量。NFL新一代数据分析系统的研究与分析高级经理Mike Band说&am…

作者头像 李华
网站建设 2026/4/20 20:48:57

大数据领域分布式存储的异构存储融合

大数据领域分布式存储的异构存储融合&#xff1a;从“信息孤岛”到“智能协同”的进化之路 一、引入&#xff1a;当“存储拼图”遇到“大数据洪流” 深夜11点&#xff0c;某电商公司的技术总监李明盯着监控屏幕&#xff0c;额头上渗出细密的汗珠——距离“双11”大促还有3小时…

作者头像 李华
网站建设 2026/4/29 19:14:27

你的善良如果缺乏 “报复能力”,在博弈论里就叫作废牌

正文 从小我们受到的教育通常是&#xff1a;吃亏是福&#xff0c;要与人为善&#xff0c;要以德报怨。 但在成年人的丛林社会里&#xff0c;我们常常发现一个扎心的真相&#xff1a; 越是好说话的人&#xff0c;越容易被欺负&#xff1b;越是懂事的孩子&#xff0c;越没有糖…

作者头像 李华
网站建设 2026/5/1 2:56:06

mellanox onyx 系统交换机基本使用

交换机基本命令 NVIDIA Docs Hub Homepage > NVIDIA Networking > Networking Software > Switch Software > NVIDIA Onyx User Manual v3.10.4006 User Interfaces Command Line Interface (CLI)

作者头像 李华
网站建设 2026/4/24 18:09:47

计算机毕业设计springboot防诈知识在线学习系统 基于SpringBoot的反诈骗科普教育平台 智慧防骗知识服务与学习管理系统

计算机毕业设计springboot防诈知识在线学习系统93z9zqrm &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。随着互联网技术的飞速发展和智能设备的全面普及&#xff0c;网络诈骗手段…

作者头像 李华