当前位置: 首页 > news >正文

Maximum Subarray Sum After at Most K Swaps

Maximum Subarray Sum After at Most K Swaps

You are given an integer array nums and an integer k.

You are allowed to perform at most k swap operations on the array.

In one swap operation, you may choose any two indices i and j and swap nums[i] and nums[j].

Return an integer denoting the maximum possible subarray sum after performing the swaps.

 

Example 1:

Input: nums = [1,-1,0,2], k = 1

Output: 3

Explanation:

  • We can swap on indices 1 and 3, resulting in the array [1, 2, 0, -1].
  • The subarray [1, 2] has a sum of 3, which is the maximum possible subarray sum after at most k = 1​​​​​​​ swap.

Example 2:

Input: nums = [4,3,2,4], k = 2

Output: 13

Explanation:

The maximum possible subarray sum after at most k = 2 swaps is the sum of the entire array, which is 13.

Example 3:

Input: nums = [-1,-2], k = 0

Output: -1

Explanation:

  • k = 0 swaps are allowed.
  • The possible subarrays are [-1][-2], and [-1, -2], with sums -1, -2, and -3 respectively.
  • Among these sums, the maximum is -1.

 

Constraints:

  • 1 <= nums.length <= 1500
  • -105 <= nums[i] <= 105
  • 0 <= k <= nums.length

 

解题思路

  首先,任何被交换进子数组的元素最终必然会留在选定的子数组中,否则交换操作没有意义。为了找到能使子数组和最大的方案,我们需要确定该选择哪个子数组。注意到数组长度 $n$ 最大只有 $1500$,这允许我们可以通过 $O(n^2)$ 的复杂度暴力枚举所有可能的子数组,从而对每个子数组计算在至多 $k$ 次交换下所能获得的最大子数组和。

  在具体实现上,我们可以先枚举子数组的左端点 $l$,随后逐步向右扩展右端点 $r$。对于任意固定的子数组区间 $[l,r]$,交换子数组内部的两个元素显然无法增加该区间的元素总和,因此有效的交换只会发生在子数组内部与外部元素之间。为了更清晰地描述这一过程,记 $S_{[l,r]}$ 为子数组内元素构成的非递减有序可重集合,其中 $S_{[l,r]}^{(i)}$ 表示集合中第 $i$ 小的元素;同时记 $S_{\overline{[l,r]}}$ 为子数组外其余元素构成的非递增有序可重集合,其中 $S_{\overline{[l,r]}}^{(i)}$ 表示集合中第 $i$ 大的元素。基于贪心思想,为了使子数组 $[l,r]$ 的和最大,我们应选择 $S_{[l,r]}$ 中最小的 $c$ 个数与 $S_{\overline{[l,r]}}$ 中最大的 $c$ 个数进行交换。这里的 $c$ 需满足约束:

  1. 交换次数不能超过限制,即 $c \le k$;
  2. 参与交换的元素数量不能超过各自集合的大小,即 $c \le \min\{|S_{[l,r]}|, |S_{\overline{[l,r]}}|\}$;
  3. 每次交换必须带来正收益,即对于任意 $1 \le i \le c$,都要满足 $S_{[l,r]}^{(i)} < S_{\overline{[l,r]}}^{(i)}$。

  对于给定的子数组,我们需要快速求出满足上述条件的最大交换次数 $c$。定义差值 $d_i = S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i)}$,随着 $i$ 的增大,$S_{[l,r]}^{(i)}$ 逐渐变大而 $S_{\overline{[l,r]}}^{(i)}$ 逐渐变小,因此 $d_i$ 具有单调不减的性质。这意味着存在一个分界点 $c$,使得当 $i \le c$ 时 $d_i < 0$,而当 $i \ge c+1$ 时 $d_i \ge 0$。利用这种二段性,我们可以通过二分找到最大的 $c$。同时为了支持在枚举过程中动态维护集合并快速查询第 $k$ 小元素及前 $k$ 小元素之和,我们可以借助平衡树或值域树状数组等数据结构,将这些操作的时间复杂度均控制在 $O(\log n)$ 级别。

  上述思路的整体时间复杂度为 $O(n^2 \log^2 n)$,其中枚举子数组的复杂度为 $O(n^2)$,而针对每个子数组进行二分并结合数据结构查询第 $k$ 小元素的复杂度为 $O(\log^2 n)$。实际上,我们可以进一步优化掉二分,将整体复杂度降至 $O(n^2 \log n)$。当固定左端点 $l$ 并向右扩展右端点 $r$ 时,每次扩展实质上是将一个元素从外部集合移入内部集合。可以证明,这一操作使得最优交换次数 $c$ 的变化幅度最多为 $1$。因此,在每次向右扩展时,我们只需检查将 $c$ 增加 $1$ 或减少 $1$ 是否依然满足条件,并据此更新 $c$ 即可,无需重新进行二分。对于博主来说这个结论很难从直觉上注意到,所以下面给出严谨的证明。

  对于固定的左端点 $l$,当右端点从 $r$ 扩展到 $r+1$ 时,内部集合加入一个元素,外部集合删除一个元素。对于内部集合,新集合的第 $i$ 小元素 $S_{[l,r+1]}^{(i)}$ 只能来自原集合的第 $i$ 小、第 $i-1$ 小或新加入的元素,故必然满足 $S_{[l,r]}^{(i-1)} \le S_{[l,r+1]}^{(i)} \le S_{[l,r]}^{(i)}$。对于外部集合,新集合的第 $i$ 大元素 $S_{\overline{[l,r+1]}}^{(i)}$ 同理必然满足 $S_{\overline{[l,r]}}^{(i)} \le S_{\overline{[l,r+1]}}^{(i)} \le S_{\overline{[l,r]}}^{(i-1)}$。

  将这两个不等式相减,可得 $S_{[l,r]}^{(i-1)} - S_{\overline{[l,r]}}^{(i)} \le S_{[l,r+1]}^{(i)} - S_{\overline{[l,r+1]}}^{(i)} \le S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i-1)}$。又因为 $S_{[l,r]}^{(i-1)} - S_{\overline{[l,r]}}^{(i)} \ge S_{[l,r]}^{(i-1)} - S_{\overline{[l,r]}}^{(i-1)}$ 且 $S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i-1)} \le S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i)}$,最终得到 $S_{[l,r]}^{(i-1)} - S_{\overline{[l,r]}}^{(i-1)} \le S_{[l,r+1]}^{(i)} - S_{\overline{[l,r+1]}}^{(i)} \le S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i)}$。记 $d_i = S_{[l,r]}^{(i)} - S_{\overline{[l,r]}}^{(i)}$,$d'_i = S_{[l,r+1]}^{(i)} - S_{\overline{[l,r+1]}}^{(i)}$,则上述不等式等价于 $d_{i-1} \le d'_i \le d_i$。

  假设在扩展到 $r+1$ 之前,最优交换次数为 $c$,即序列 $d$ 的前 $c$ 项为负数,第 $c+1$ 项起为非负数,满足 $d_c < 0$ 且 $d_{c+1} \ge 0$。在扩展到 $r+1$ 后,根据推论 $d'_{c+2} \ge d_{c+1} \ge 0$,这意味着新序列第 $c+2$ 项及之后的所有项均非负,负数最多只有 $c+1$ 个,因此 $c$ 最多增加 $1$;同时,由于 $d'_{c-1} \le d_{c-1} \le d_c < 0$,新序列第 $c-1$ 项及之前的项均为负数,负数至少有 $c-1$ 个,因此 $c$ 最多减少 $1$。

  所以,当右端点扩展时,最优交换次数 $c$ 的变化幅度不超过 $1$。得证。

  AC 代码如下,时间复杂度为 $O(n^2\log{n})$:

const int N = 1505;int xs[N], sz;
struct Fenwick {long long tr1[N], tr2[N];Fenwick() {memset(tr1, 0, sz + 1 << 3);memset(tr2, 0, sz + 1 << 3);}int lowbit(int x) {return x & -x;}void add(int x, int c, int v) {for (int i = x; i <= sz; i += lowbit(i)) {tr1[i] += c;tr2[i] += v;}}int kth(int k) {int ret = 0;for (int i = __lg(sz); i >= 0; i--) {int t = ret | 1 << i;if (t <= sz && tr1[t] < k) {ret = t;k -= tr1[t];}}return ret + 1;}long long query(int k) { // 求前k小元素之和。采用与kth相同的二分方式,处理第k小有多个重复值的情况if (!k) return 0;long long x = 0, ret = 0;for (int i = __lg(sz); i >= 0; i--) {int t = x | 1 << i;if (t <= sz && tr1[t] < k) {x = t;ret += tr2[t];k -= tr1[t];}}ret += 1ll * xs[x + 1] * k; // 此时k为剩余需累加的元素个数,xs[x+1]为第k小的值return ret;}
};class Solution {
public:long long maxSum(vector<int>& nums, int k) {int n = nums.size();sz = 0;for (auto &x : nums) {xs[++sz] = x;}sort(xs + 1, xs + sz + 1);sz = unique(xs + 1, xs + sz + 1) - xs - 1;for (auto &x : nums) {x = lower_bound(xs + 1, xs + sz + 1, x) - xs;}long long ret = -1e18;for (int i = 0; i < n; i++) {Fenwick tr1, tr2;for (auto &x : nums) {tr2.add(x, 1, xs[x]);}long long s = 0;for (int j = i, c = 0; j < n; j++) {tr1.add(nums[j], 1, xs[nums[j]]);tr2.add(nums[j], -1, -xs[nums[j]]);s += xs[nums[j]];int t = j - i + 1, flag = 0;if (c < k && c < t && c < n - t && tr1.kth(c + 1) < tr2.kth(n - t - c)) c++, flag = 1;if (!flag && c && tr1.kth(c) >= tr2.kth(n - t - c + 1)) c--;ret = max(ret, s + tr2.query(n - t) - tr2.query(n - t - c) - tr1.query(c));}}return ret;}
};

 

参考资料

  至多 K 次交换后最大子数组和【力扣周赛 506】:https://www.bilibili.com/video/BV1ptJw6hENZ/

http://www.jsqmd.com/news/1025383/

相关文章:

  • CANN OAM-Tools运维工具包手把手实战入门:基于昇腾NPU的oamget/oamset/oamsetper设备诊断命令从安装部署到生产环境实战的全流程操作指南
  • 终极开源金融大模型:Cornucopia-LLaMA-Fin-Chinese 完整部署与实战指南 [特殊字符]
  • 2026北京名包回收榜单,高报价靠谱门店汇总 - 名奢变现站
  • 2026年6月最新欧米茄中国官方售后电话热线服务地址网点客服 - 速递信息
  • 百万外贸订单险失效!实地尽调规避科威特骗货风险
  • 5家靠谱铸铝门厂家挑选指南,高端别墅入户门工厂实测对比 - 门业测评
  • LiveKit完整指南:5分钟搭建你的第一个实时音视频应用
  • AI驱动测试自动化:基于Codex与DeepSeek的Selenium/Appium实战指南
  • 一条线公排模式开发解析
  • 【Linux】系统级文件I/O与文件描述符深度剖析
  • 2026济南奢侈品包包回收行业白皮书,正规门店全域实测 - 薛定谔的梨花猫
  • 如何快速掌握Python量化投资分析:QuantStats完整指南
  • 金融行业数字化——解读金融数据库存算分离架构选型白皮书【附全文阅读】
  • Linux Pulseaudio深度解析之pa_context_set_sink_input_volume用流程与实战(五十九)
  • 2026内衬不锈钢复合管厂家到底哪家强 - 速递信息
  • 2026南昌公司变更避坑TOP榜单!股权/地址/法人变更均可 - 江西企服智库
  • 2026北京卡地亚手表回收深度测评,禹竞名奢汇变现首选,六大靠谱商家综合实力盘点 - 名奢变现站
  • EVM3588-B开发板+NPU+Qwen2.5-3B-Instruct(一)
  • 2026上海名包回收门店汇总:5家甄选好评门店,各有千秋 - 奢侈品回收测评
  • 2026上海爱马仕包包回收口碑榜:5家门店排名,收的顶位居前列 - 奢侈品回收测评
  • Java计算机毕设之基于 SpringBoot 的餐饮收支台账与票据管理系统设计 餐饮经营财务数据统计分析系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 消失模白膜烘干设备主流品牌客观盘点排行 - 互联网科技品牌测评
  • 苏州宠物店探店实拍,新手选购宠物避坑指南 - 园友3800037
  • 如何快速掌握物理信息神经算子(PINO):从入门到实践的完整教程
  • Havenlon哲学:创业是为一个无法被忽视的问题在寻找系统化出口
  • 2026 钐钴磁铁厂家推荐攻略,如何挑选靠谱钐钴磁铁源头生产厂家不踩坑 - 商业新知
  • 佛山冰箱维修漏水怎么办?2026年专业检修方案与平台对比分析 - 简单到家
  • 2026梅州中高端家装选品指南:本地服务商适配与案例参考 - 速递信息
  • 武汉黄金回收避坑指南:四种套路一次拆穿,帮你少走很多弯路 - 奢侈品回收测评
  • 【麒麟系统】软件 RAID、逻辑卷快照、逻辑卷镜像技术选型参考(Linux 运维实战)