当前位置: 首页 > 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.gsyq.cn/news/1537248.html

相关文章:

  • 2026北京名包回收榜单,高报价靠谱门店汇总 - 名奢变现站
  • 百万外贸订单险失效!实地尽调规避科威特骗货风险
  • 如何快速掌握Python量化投资分析:QuantStats完整指南
  • 5家靠谱铸铝门厂家挑选指南,高端别墅入户门工厂实测对比 - 门业测评
  • 【Linux】系统级文件I/O与文件描述符深度剖析
  • 金融行业数字化——解读金融数据库存算分离架构选型白皮书【附全文阅读】
  • EVM3588-B开发板+NPU+Qwen2.5-3B-Instruct(一)
  • 2026上海名包回收门店汇总:5家甄选好评门店,各有千秋 - 奢侈品回收测评
  • 合肥南亚理工学校招生电话,热门专业,报名要求,收费标准,学校位置详情 - hflgzz
  • 佛山冰箱维修漏水怎么办?2026年专业检修方案与平台对比分析 - 简单到家
  • 武汉黄金回收避坑指南:四种套路一次拆穿,帮你少走很多弯路 - 奢侈品回收测评
  • go | 环境安装和快速入门
  • Nano Banana Pro:专业级AI图像生成的四大底层突破
  • 2026年宁波减肥训练营2026宁波封闭式减肥训练营深度实测:吃住全包 + 签约减重,东吴这家营地凭实力打破行业乱象 - 速递信息
  • 海口家电维修平台服务对比:2026年行业数据驱动的消费决策参考 - 简单到家
  • 无锡哪家宠舍靠谱 7家实地探访给出答案 - 园友3800037
  • OpenClaw本地AI工作流部署全解析:PowerShell、Ollama镜像与Qwen3.5:9b实战
  • 【问答】青岛防水维修一般质保多久?不同部位质保标准参考 - 青岛防水品牌推荐
  • Python 数据分析实战:Pandas+Matplotlib 从入门到可视化报表
  • 解锁AI写专著密码!AI专著撰写工具,20万字专著快速成型!
  • 2026实测推荐:小红书视频怎么去水印?复制链接就能解析保存的3个小程序 - 效率工具研究所
  • 20251202马思钊 2025-2026-2 实验四 Python综合实践
  • 新手在无锡买猫狗 哪家宠物门店值得信赖? - 园友3800037
  • BallonTranslator:让漫画翻译变得像聊天一样简单的AI工具
  • 2026 粘结钕铁硼厂家推荐|高精度异形磁体定制,新能源电机磁瓦生产厂商 - 商业新知
  • Steam Deck控制器Windows驱动完全指南:SWICD让你的游戏体验无缝衔接
  • 2026 好用的素颜霜早八通勤实测|100 人 28 天横评榜单 黄皮自然抗暗沉优选 - 速递信息
  • 2026银行秋招面试技巧班深度评测:4家头部机构对比,谁能帮你突破最后一关 - 互联网科技品牌测评
  • 杭州购宠避坑指南:4家靠谱实体门店实测推荐 - 园友3800037
  • 2026银行网申修改机构横向评测:精准适配不同考生,破解网申死难题 - 互联网科技品牌测评