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

千问 LeetCode 2382. 删除操作后的最大子段和 public long[] maximumSegmentSum(int[] nums, int[] removeQueries)

LeetCode 2382. 删除操作后的最大子段和 是一道典型的“逆向思维 + 并查集”题目。正向模拟删除非常困难,因为每次删除会分裂区间,难以高效维护所有子段的最大和。但如果我们从后往前逆序添加元素,就可以用并查集(Union-Find)来合并相邻的连续段,并动态维护最大子段和。

✅ 正确高效的 Java 实现

class Solution {
public long[] maximumSegmentSum(int[] nums, int[] removeQueries) {
int n = nums.length;
// parent[i] 表示 i 所在集合的根节点;sum[i] 表示以 i 为根的集合的总和
int[] parent = new int[n + 1]; // 多一位用于处理右边界
long[] sum = new long[n + 1];

// 初始化并查集:每个位置初始时未激活(sum=0),parent指向自己
for (int i = 0; i = 1; i--) {
int idx = removeQueries[i]; // 当前要恢复的位置

// 激活该位置:初始子段和为 nums[idx]
sum[idx] = nums[idx];

// 尝试与右边已激活的段合并(idx+1 到其根)
int rightRoot = find(idx + 1, parent);
if (rightRoot 0) {
int leftRoot = find(idx - 1, parent);
if (leftRoot != idx - 1 || sum[leftRoot] > 0) { // 左边已激活
sum[idx] += sum[leftRoot];
parent[leftRoot] = idx;
}
}

// 更新当前最大子段和
maxSoFar = Math.max(maxSoFar, sum[idx]);
ans[i - 1] = maxSoFar;
}
// 最后一次删除后数组全空,ans[n-1] = 0(默认值)
return ans;
}

private int find(int x, int[] parent) {
if (parent[x] != x) {
parent[x] = find(parent[x], parent);
}
return parent[x];
}
}

🧠 为什么这样写?关键点解析

1. 逆向思维(Reverse Thinking)
- 最终状态:所有元素都被删除 → 所有子段和为 0。
- 从后往前:第 n-1 次删除后 → 第 n-2 次... → 初始状态。
- 每次“恢复”一个元素,相当于合并左右已存在的连续段。

2. 并查集设计
- parent[i]:i 的父节点。
- sum[i]:仅当 i 是根节点时,sum[i] 表示该连续段的总和。
- 合并策略:
- 恢复位置 idx 时,检查 idx-1 和 idx+1 是否已被恢复(即 sum[root] > 0)。
- 将左右段的根合并到 idx(或统一合并方向,如只向右合并)。

💡 更简洁的合并方式(推荐):
每次只将 idx 合并到 idx+1 的根,这样天然处理了右合并;左合并会在后续处理 idx-1 时自动完成(因为它会向右合并到 idx)。
这是许多题解采用的技巧,避免显式判断左右。

🔁 推荐写法(只向右合并,更简洁)

class Solution {
public long[] maximumSegmentSum(int[] nums, int[] removeQueries) {
int n = nums.length;
int[] parent = new int[n + 1];
long[] sum = new long[n + 1];
for (int i = 0; i 0; i--) {
int x = removeQueries[i];
int root = find(x + 1, parent); // 右边段的根
parent[x] = root; // x 合并到右边
sum[root] += sum[x] + nums[x]; // 累加 x 及其左边可能已合并的段
ans[i - 1] = Math.max(ans[i], sum[root]);
}
return ans;
}

private int find(int x, int[] parent) {
return parent[x] == x ? x : (parent[x] = find(parent[x], parent));
}
}

✨ 关键洞察:
- sum[x] 在 x 被恢复前为 0;若 x-1 已被恢复,则 x-1 会合并到 x(通过 x-1 向右合并),此时 sum[x] 已包含左边段的和。
- 因此 sum[root] += sum[x] + nums[x] 自动包含了 左边段 + x + 右边段 的总和!

📌 示例验证
输入:
nums = , removeQueries =
输出:

逆序恢复过程:
1. 恢复 removeQueries=1 → → max=2
2. 恢复 removeQueries=4 → → max=2
3. 恢复 removeQueries=2 → → max=7
4. 恢复 removeQueries=3 → → max=14
5. 初始状态(不恢复 removeQueries)→ ans=14

⏱️ 复杂度
- 时间:O(n α(n)) ≈ O(n),α 是阿克曼反函数(近乎常数)。
- 空间:O(n)

此解法高效且符合 LeetCode 高分题解风格,建议掌握逆向 + 并查集的核心思想!

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

相关文章:

  • MAC地址失效下基于射频指纹的WiFi设备识别技术
  • Claude与LSP融合:打造深度理解代码的智能编程助手
  • 使用Taotoken后API调用延迟与稳定性可观测性体验
  • 开源健身数据平台ZWISERFIT:自托管、全栈技术栈与数据隐私实践
  • Uniapp小程序二手商城系统 带协同过滤推荐算法
  • 消防通道门基础知识全面解析
  • Python +Vue实战:从零搭建中国电影票房数据可视化分析系统(附完整源码)
  • 2026年Q2无锡注册资金变更服务选型全维度技术指南:无锡变更公司名字/无锡变更公司抬头/无锡地址变更/无锡增资/选择指南 - 优质品牌商家
  • AI赋能代码审计:grits-audit项目实战与LLM应用解析
  • B站缓存视频转换秘籍:3分钟解锁m4s转MP4的终极方案
  • EPUB转有声书:基于Python的自动化实现与TTS技术实践
  • OpenClaw:重塑人机协作的开源 AI 智能体
  • 【LangChain】 Runnable 链式调用深度解析:从 `itemgetter` 到 `RunnableLambda`
  • 2026Q2不锈钢灭火器箱技术指南:四川灭火器厂家、四川灭火器回收、四川灭火器年检、四川灭火器灌装、四川灭火器维修选择指南 - 优质品牌商家
  • 如何抓取某音视频的互动数据
  • claw-mesh:参数化设计如何革新3D打印机械爪的开发流程
  • 从Harvest项目看数据采集框架的工程化设计与实战实现
  • 别再只调BERT了!用PyTorch从零搭建BiLSTM-CRF中文NER模型(附完整代码与CLUE数据集实战)
  • 深入解析Java基础之基础
  • MIMO OFDM系统中的波束成形技术与定位感知优化
  • 别再一个个点菜单了!MathType 7.4.8快捷键保姆级清单,效率翻倍不是梦
  • 构建Discord与GitHub知识库:llmcord项目实战与RAG应用
  • 打造高效开发者工作流:从环境配置到心流营造的完整指南
  • 2026年近期陕西电脉冲除垢设备市场深度解析与核心服务商推荐 - 2026年企业推荐榜
  • Kubernetes的daemonset管理
  • 021、LVGL显示驱动接口详解
  • 禁止edge浏览器更新
  • RDP Wrapper Library技术架构深度解析
  • 从月薪8K到年薪80W,我只做对了一件事:深耕垂直领域
  • 从真题到实战:第十四届蓝桥杯JavaB组省赛核心解题思路与代码精讲